这篇文章说下tox、subunit和testr。
1.python-subunit
先看python-subunit(可以参考:http://www.tech-foo.net/making-the-most-of-subunit.html):
subunit可以将多种不同语言、不同测试库的数据变成一个可以被以后分析的流式文件,比如:
python -m subunit.run discover .
当前目录下有如下测试文具:
from unittest import TestCase
class MySimpleTests(TestCase):
def test_something_that_passes(self):
self.assertEqual(4, 2*2)
def test_something_that_fails(self):
self.assertEqual(5, 2*2)
则上面的命令会输出一个二进制的流式文件:
[root@RHEL01 test]# python -m subunit.run discover .
?)=4test_example.MySimpleTests.test_something_that_failsui"B?)>5test_example.MySimpleTests.test_something_that_passes???+@FU???4test_example.MySimpleTests.test_something_that_fails???(?+pA?U???x?4test_example.MySimpleTests.test_something_that_fails3text/x-traceback; charset="utf8"; language="python" tracebackATraceback (most recent call last):
File "/tmp/test/test_example.py", line 10, in test_something_that_fails
self.assertEqual(5, 2*2)
File "/usr/lib64/python2.6/unittest.py", line 349, in failUnlessEqual
(msg or '%r != %r' % (first, second))
AssertionError: 5 != 4
t0#?+@FU???x?4test_example.MySimpleTests.test_something_that_fails???ܳ+@GU????5test_example.MySimpleTests.test_something_that_passes@??+@GU???k?5test_example.MySimpleTests.test_something_that_passes{?V]0;root@RHEL01:/tmp/test[root@RHEL01 test]#
流式文件中包含了测试结果的所有信息,可以通过subunit提供的工具查看,比如:
[root@RHEL01 test]# python -m subunit.run discover . | subunit-stats
Total tests: 2
Passed tests: 1
Failed tests: 1
Skipped tests: 0
Seen tags:
2.testrsubunit产生的测试结果可以由很多用处,但是得有好点的工具去分析呀。testr就是用来做这个的,其会跟踪subunit类型的文件,然后分析其内容。比如:
python -m subunit.run discover . > test_result
test_result就是我们的测试结果了,我们看下如何分析:
[root@RHEL01 test]# testr load < test_result
======================================================================
FAIL: test_example.MySimpleTests.test_something_that_fails
tags: worker-0
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test/test_example.py", line 10, in test_something_that_fails
self.assertEqual(5, 2*2)
File "/usr/lib64/python2.6/unittest.py", line 349, in failUnlessEqual
(msg or '%r != %r' % (first, second))
AssertionError: 5 != 4
Ran 2 tests in 216.439s (+216.433s)
FAILED (id=5, failures=1)
[root@RHEL01 test]# testr stats
runs=6
[root@RHEL01 test]# testr failing
======================================================================
FAIL: test_example.MySimpleTests.test_something_that_fails
tags: worker-0
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test/test_example.py", line 10, in test_something_that_fails
self.assertEqual(5, 2*2)
File "/usr/lib64/python2.6/unittest.py", line 349, in failUnlessEqual
(msg or '%r != %r' % (first, second))
AssertionError: 5 != 4
Ran 1 tests in 0.000s
FAILED (id=5, failures=1)
可以看到,testr可以分析结果。
但是我们不想重定向输出,我们想testr执行个命令就直接运行测试,生成并保存subunit,然后load到testr中,这个时候可以配置.testr.conf文件,告诉testr测试的运行命令,这个时候它就会帮我们做这些事情了:
[root@RHEL01 test]# cat .testr.conf
[DEFAULT]
test_command=python -m subunit.run discover . $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list
然后执行testr run就可以了。如果一次测试跑完后由错误,那么在修正后直接运行:
testr run --failing
就会的运行fail的测试用例。
另外,setuptools里提供了对testr的支持。用法一般为:
[root@RHEL01 test]# python setup.py testr --testr-args="--subunit " | subunit-trace -f
3.tox上面的testr和subunit,已经可以让我们对测试结果有一个很好的分析了。但是在python程序测试的时候,我们一般希望在virtualenv中跑测试用例,这样不会影响我们的开发环境。那么有没有工具可以让我们在跑测试的时候帮我们新建立一个venv,同时按照最新的py文件,然后运行上面的testr和subunit呢?tox就是这么个工具。
tox的配置文件很简单,比如官网的例子:
# content of: tox.ini , put in same dir as setup.py
[tox]
envlist = py26,py27
[testenv]
deps=pytest # install pytest in the venvs
commands=py.test # or 'nosetests' or ...
在运行的时候,指定-py26/-py27这种在envlist中指定的环境,即可运行具体的测试。测试的命令由commands提供,环境默认是配置好的,当然也可以自己设置,比如:
[tox] envlist = py24,py25,py26,py27 [testenv] deps=unittest2 commands=unit2 discover [] [testenv:py26] commands= unit2 discover [] sphinx-build -b doctest docs html sphinx-build docs html deps = unittest2 sphinx [testenv:py27] commands= unit2 discover [] sphinx-build -b doctest docs html sphinx-build docs html deps = unittest2 sphinx