Python 的 unittest 库如何匹配通过 -p 参数传递的模式?
How does Python's unittest library match patterns passed via the -p parameter?
我正在 运行 将以下命令 运行 仅用于位于名为 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
选项的模式不接受正则表达式。那么如何指定我希望的测试 运行?
通常,您通过 -p
参数传递给 unittest
的所有内容都通过 TestLoader::_match_path()
method which then invokes chain of functions fnmatch()
→ fnmatchcase()
→ _compile_pattern()
→ translate()
from 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-like" 模式转换为的确切过程最终的正则表达式。
我想出了如何绕过 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[@]}
我正在 运行 将以下命令 运行 仅用于位于名为 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
选项的模式不接受正则表达式。那么如何指定我希望的测试 运行?
通常,您通过 -p
参数传递给 unittest
的所有内容都通过 TestLoader::_match_path()
method which then invokes chain of functions fnmatch()
→ fnmatchcase()
→ _compile_pattern()
→ translate()
from 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-like" 模式转换为的确切过程最终的正则表达式。
我想出了如何绕过 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[@]}