【问题标题】:How does Python's unittest library match patterns passed via the -p parameter?Python 的 unittest 库如何匹配通过 -p 参数传递的模式?
【发布时间】:2020-02-21 18:42:50
【问题描述】:

我正在运行以下命令以仅运行位于名为 test_CO2.py 的文件中的测试

python3.7 -m unittest discover -s some_path/tests/ -p "*CO2*"

我的文件夹结构如下所示:

some_path/tests/
  CO2
    test_CO2.py
  battery
    test_battery.py
  tank
    test_tank.py

我想指定运行的测试。例如,如果我只想测试水箱和 CO2 代码,我该怎么做?我想通过以下正则表达式: \w*(CO2|tank)\w*.py 找不到任何测试。

我认为传递给-p 选项的模式不接受正则表达式。那么如何指定我希望运行的测试?

【问题讨论】:

  • 对于它的价值,这是 unittest 解析您的 -p 参数,而不是核心 Python。这些通常是通过通配符而不是正则表达式来完成的。

标签: python regex python-3.x python-unittest


【解决方案1】:

通常,您通过-p 参数传递到unittest 的所有内容都通过TestLoader::_match_path() method 处理,然后调用函数链fnmatch()fnmatchcase()_compile_pattern()translate()fnmatch library

translate() 函数将您原来的 -p 参数转换为正则表达式,然后用于名称匹配。

fnmatch() 函数的文档说明了这一点:

Patterns are Unix shell style:
*       matches everything
?       matches any single character
[seq]   matches any character in seq
[!seq]  matches any char not in seq

据我所知,这就是它可以做的程度。 所有其他字符都被转义以进行字面匹配

示例:我将正则表达式 a|b 作为模式传递。 translate() 函数以(?s:p\|m)\Z 的形式返回最终的正则表达式。 管道字符被转义

如果您特别好奇,请查看fnmatch lib 的translate() 函数here - 如果您想知道将“类似glob”的模式转换为最终正则表达式的确切过程。

【讨论】:

    【解决方案2】:

    我想出了如何绕过 unittest 的限制。

    我可以使用 python3.7 -m unittest path_to_some_test 运行特定测试

    # take regex and find all files that match
    # clean up results. i.e. remove './' from output
    test_paths_result=()
    test_paths=$(find . -regextype posix-extended -regex "${regex}")
    for file_path in ${test_paths}; do
      # save clean results to array variable
      test_paths_result+=("${file_path:2}")
    done
    
    echo "Running test files that match the following expression: '${regex}'"
    python3.7 -m unittest ${test_paths_result[@]}
    

    【讨论】:

      猜你喜欢
      • 2012-07-07
      • 2023-03-28
      • 1970-01-01
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多