带有文档测试、覆盖率和并行性的 Python 测试发现
Posted
技术标签:
【中文标题】带有文档测试、覆盖率和并行性的 Python 测试发现【英文标题】:Python test discovery with doctests, coverage and parallelism 【发布时间】:2013-06-03 16:00:29 【问题描述】:...还有一匹小马!不,认真的。我正在寻找一种组织“正常工作”的测试的方法。大多数事情确实有效,但并非所有部分都可以组合在一起。所以这就是我想要的:
自动发现测试。这包括文档测试。请注意,doctest 的总和不得作为单个测试出现。 (即不是 py.test --doctest-modules 所做的) 能够并行运行测试。 (类似于 xdist 中的 py.test -n) 生成覆盖率报告。 让python setup.py test
正常工作。
我目前的方法涉及tests
目录和load_tests protocol。包含的所有文件都命名为test_*.py
。如果我创建一个包含以下内容的文件test_doctests.py
,这将使python -m unittest discover
正常工作。
import doctest
import mymodule1, mymodule2
def load_tests(loader, tests, ignore):
tests.addTests(doctest.DocTestSuite(mymodule1))
tests.addTests(doctest.DocTestSuite(mymodule2))
return tests
这种方法还有一个好处是可以使用 setuptools 并提供 setup(test_suite="unittest2.collector")
。
但是这种方法存在一些问题。
coverage.py 期望运行一个脚本。所以我不能在这里使用 unittest2 发现。 py.test 不运行 load_tests 函数,因此它找不到 doctests 并且--doctest-modules
选项是废话。
nosetests 运行load_tests
函数,但不提供任何参数。这在鼻子一侧看起来完全坏了。
我怎样才能让事情变得比这更好或解决上面的一些问题?
【问题讨论】:
不错。你的问题正是我正在寻找的答案。 :-) 关于coverage.py:使用coverage -m unittest2 discover
应该可以工作(至少它在Py2.7 中对unittest
有效)。
【参考方案1】:
这是一个老问题,但对于我们中的一些人来说,这个问题仍然存在!我只是在研究它,并找到了一个类似于 kaapstorm 的解决方案,但输出要好得多。我使用py.test
运行它,但我认为它应该在测试运行器之间兼容:
import doctest
from mypackage import mymodule
def test_doctest():
results = doctest.testmod(mymodule)
if results.failed:
raise Exception(results)
在失败案例中我最终得到的是打印的 stdout 输出,您可以通过手动运行 doctest 获得,另外一个异常如下所示:
Exception: TestResults(failed=1, attempted=21)
正如 kaapstrom 所提到的,它没有正确计算测试(除非有失败),但我发现如果覆盖率恢复到高水平,这并不值得 :)
【讨论】:
【参考方案2】:我用鼻子,当我遇到同样的问题时发现了你的问题。
我最终得到的结果并不漂亮,但它确实运行了测试。
import doctest
import mymodule1, mymodule2
def test_mymodule1():
assert doctest.testmod(mymodule1, raise_on_error=True)
def test_mymodule2():
assert doctest.testmod(mymodule2, raise_on_error=True)
不幸的是,它将模块中的所有文档测试作为单个测试运行。但如果出现问题,至少我知道从哪里开始寻找。失败会导致 DocTestFailure,并带有一条有用的消息:
DocTestFailure: <DocTest mymodule1.myfunc from /path/to/mymodule1.py:63 (4 examples)>
【讨论】:
虽然它适用于鼻子,但失败消息现在完全是废话。海事组织,这简直太有用了。我认为这个解决方案不如提出的替代方案。以上是关于带有文档测试、覆盖率和并行性的 Python 测试发现的主要内容,如果未能解决你的问题,请参考以下文章