6.5 测试序列与并行
在执行大量测试时,按它们被运行的情况进行分析是很有用的。类似nosetests这样的工具只是将结果输出到stdout,即标准输出,但这对测试结果的解析或分析并不方便。
subunit(https://pypi.python.org/pypi/python-subunit)是用来为测试结果提供流协议(streaming protocol)的一个Python模块。它支持很多有意思的功能,如聚合测试结果1或者对测试的运行进行记录或归档等。
使用subunit运行测试非常简单:
$ python -m subunit.run test_scenario
这条命令的输出是二进制数据,所以除非有能力直接阅读subunit协议,否则在这里直接再现它的输出结果实在是没什么意义。不过,subunit还支持一组将其二进制流转换为其他易读格式的工具,如示例6.12所示。
示例6.12 使用subunit2pyunit
$ python -m subunit.run test_scenario | subunit2pyunit test_scenario.TestPythonErrorCode.test_python_status_code_handling(Not found) test_scenario.TestPythonErrorCode.test_python_status_code_handling(Not found) ... ok test_scenario.TestPythonErrorCode.test_python_status_code_handling(Client error) test_scenario.TestPythonErrorCode.test_python_status_code_handling(Client error) ... ok test_scenario.TestPythonErrorCode.test_python_status_code_handling(Server error) test_scenario.TestPythonErrorCode.test_python_status_code_handling(Server error) ... ok --------------------------------------------------------- Ran 3 tests in 0.061s OK
这样的结果就容易理解了。你应该可以认出这个关于场景测试的测试集来自6.4节。其他值得一提的工具还有subunit2csv、subunit2gtk和subunit2junitxml。
subunit还可以通过传入discover参数支持自动发现哪个测试要运行。
$ python -m subunit.run discover | subunit2pyunit test_scenario.TestPythonErrorCode.test_python_status_code_handling(Not found) test_scenario.TestPythonErrorCode.test_python_status_code_handling(Not found) ... ok test_scenario.TestPythonErrorCode.test_python_status_code_handling(Client error) test_scenario.TestPythonErrorCode.test_python_status_code_handling(Client error) ... ok test_scenario.TestPythonErrorCode.test_python_status_code_handling(Server error) test_scenario.TestPythonErrorCode.test_python_status_code_handling(Server error) ... ok --------------------------------------------------------- Ran 3 tests in 0.061s OK
也可以通过传入参数--list只列出测试但不运行。要查看这一结果,可以使用subunit-ls。
$ python -m subunit.run discover --list | subunit-ls --exists test_request.TestPython.test_bad_status_code test_request.TestPython.test_ioerror test_request.TestPython.test_python_is test_request.TestPython.test_python_is_not test_scenario.TestPythonErrorCode.test_python_status_code_handling
提示
可以使用--load-list选项指定要运行的测试的清单而不是运行所有的测试。
在大型应用程序中,测试用例的数量可能会多到难以应付,因此让程序处理测试结果序列是非常有用的。testrepository包(https://pypi.python.org/pypi/testrepository)目的就是解决这一问题,它提供了testr程序,可以用来处理要运行的测试数据库。
$testr init $ touch .testr.conf % python -m subunit.run test_scenario | testr load Ran 4 tests in 0.001s PASSED (id=0) $ testr failing PASSED (id=0) $ testr last Ran 3 tests in 0.001s PASSED (id=0) $ testr slowest Test id Runtime (s) ---------------------------------------------- ----------- test_python_status_code_handling(Not found) 0.000 test_python_status_code_handling(Server error) 0.000 test_python_status_code_handling(Client error) 0.000 $ testr stats runs=1
一旦subunit的测试流被运行并加载到testrepository,接下来就很容易使用testr命令来操作了。
显然,每次手工处理要运行的测试是很烦人的。因此,应该“教会”testr如何执行要运行的测试,以便它可以自己去加载测试结果。这可以通过编辑项目的根目录中的.testr.conf文件(见示例6.13)来实现。
示例6.13 .testr.conf文件
[DEFAULT] test_command=python -m subunit.run discover . $LISTOPT $IDOPTION 1 test_id_option=--load-list $IDFILE 2 test_list_option=--list 3
1 执行testr run时要运行的命令。
2 加载测试列表要运行的命令。
3 列出测试要运行的命令。
第一行的test_command是最关键的。现在只需要运行testr run就可以将测试加载到testrepository中并执行。
注意
如果习惯用nosetests,testr run现在是等效的命令。
另外两个选项可以支持测试的并行运行。通过给testr run加上--prallel选项即可轻松实现,如示例6.14所示。并行运行测试可以极大地加速测试过程。
示例6.14 运行testr run --parallel
$ testr run --parallel running=python -m subunit.run discover . --list running=python -m subunit.run discover . --load-list /tmp/tmpiMq5Q1 running=python -m subunit.run discover . --load-list /tmp/tmp7hYEkP running=python -m subunit.run discover . --load-list /tmp/tmpP_9zBc running=python -m subunit.run discover . --load-list /tmp/tmpTejc5J Ran 26 (+10) tests in 0.029s (-0.001s) PASSED (id=7, skips=3)
在后台,testr运行测试列出操作,然后将测试列表分成几个子列表,并分别创建Python进程运行测试的每个子列表。默认情况下,子列表的数量与当前使用的机器的CPU数目相等。可以通过加入--concurrency标志设置进程的数目。
$ testr run --parallel --concurrency=2
可以想象,类似subunit和testrepository这样的工具将为测试效率的提升带来更多可能,而本节只是一个大概介绍。熟悉这些工具是非常值得的,因为测试会极大地影响你将要开发和发布的软件的质量。利用这些有力的工具能够节省很多时间。
testrepository也可以同setuptools集成,并且为其部署testr命令。这使得与基于setup.py工作流的集成更加容易,例如,可以围绕setup.py记录整个项目。setup.py testr命令可以接受一些选项,如--testr-args(通过它可以为testr加入更多选项)或者--coverage(这将在下一节介绍)。
1甚至可以支持来自不同源程序或语言的测试结果。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论