跳转到: 导航, 搜索

Testr

testr

testr 是一个测试运行器,是 testrepository 的一部分。testrepository 拥有优秀的 文档 和非常有用的 手册。此 wiki 页面将尝试浓缩其中大部分信息。testr 的工作方式是使用你的测试运行器来列出所有测试,它将此列表分区成与当前机器上可用 CPU 数量匹配的多个分区,然后 fork 该数量的测试运行器,每个运行器获得其自身测试列表的分区。期望测试运行器向 testr 发送 subunit 消息,以便 testr 可以跟踪测试的成功和失败以及其他统计信息。

简而言之,testr 将并行运行你的测试(因此速度更快),并且它会保留结果的可靠日志。

依赖树

使用 testr

Nova、neutron 和 keystone 是目前使用 testr 的三个 OpenStack 项目(nova 首先移植了困难的项目)。要查看某个项目是否使用 testr,请查看项目根目录的 tox.ini 文件中 [testenv] 部分的 commands 设置。

要使用 testr,你可以使用现有的包装器,tox 和 run_tests.sh。

tox -epy27
# or
tox -epy26
# or
tox -ecover
# or
run_tests.sh

为 testr 编写测试

有一些 nose 结构与 testr 配合不好。((请在此处详细说明。)) 将运行 Nova 的所有单元测试,并使用 testr。你可以使用正则表达式指定要运行哪些测试。看起来不支持完整的正则表达式,但尾部的 * 通配符有效。正则表达式覆盖测试的完整路径。例如,nova.tests.test_something.TestSomething.test_this_one_unit 或 "ceilosca.ceilometer.tests.unit.storage.*"

tox -epy27 -- <test_name_regex>
# or
run_tests.sh <test_name_regex>

testr 直接运行时也可能非常有用。首先 source 你的测试 venv。

source .tox/py27/bin/activate

在 source venv 后,我们可以直接运行 testr。

testr help

testr run --parallel
testr run --parallel test_name_regex

测试运行后,你可以查看失败的测试,然后仅运行该测试列表。

testr failing
testr run --failing

测试日志

你会发现 testr 将测试日志保存在 .testrepository/$TEST_RUN_NUMBER 中。这些日志是 subunit 流,用于确定当你运行 testr failing 时哪些测试失败。这有几个很好的结果,你可以将这些日志传递给其他人以协作一组失败的测试,编写脚本来解析和转换日志非常容易(参见 python-subunit 及其 subunit 解析器),并且你可以使用日志来帮助重现错误,方法是使用日志 feed 测试运行器提供的测试列表。

重现失败

一种重现失败的方法是在它们第一次失败时运行的相同顺序中重新运行它们。要获取此测试列表,我们首先需要运行失败测试的子进程的工作器名称。查看 .testrepository/$LAST_TEST_RUN_NUMBER(你可能需要检查 .stestr 而不是 .testrepository),找到失败的测试,然后在 tags 部分你应该看到类似这样的内容

tags: worker-3

有了这个工作器名称,我们可以提取在该测试运行中该工作器上运行的测试列表。

source .tox/py27/bin/activate
# NOTE: You might need to use "stestr" if you don't have "testr".
testr last --subunit | subunit-filter -s --xfail --with-tag=worker-3 | subunit-ls > slave-3.list

使用此测试列表,我们可以使用以下命令以导致失败的相同顺序运行该测试集

source .tox/py27/bin/activate
testr run --load-list=slave-3.list

testr 还带有一个非常强大的自动化测试二分法功能,它将尝试确定重现失败所需的最小测试集,这些失败是由测试相互干扰引起的。要使用此功能,请运行

source .tox/py27/bin/activate
testr run --analyze-isolation

在失败的测试运行之后。

如果分析器无法确定冲突,你可能需要重复这些步骤,直到失败工作器中的测试列表越来越小,直到你可以获得一个相当小的测试集进行比较,并查看可能存在冲突的位置,例如相同的全局变量上的常见模拟。

调试 (pdb) 测试

调试测试需要使用 testtools.run。此处 的 bug 列表 解释了为什么不支持直接 pdb 支持。

有一个简单的过程可以在测试中使用 pdb。首先,生成要运行的测试列表。

source .tox/py27/bin/activate
testr list-tests <test_name_regex> > my-list

注意:<test_name_regex> 与文档中先前提到的相同。你还可以编辑 my-list 文件以缩小要运行的测试范围。现在将列表作为选项传递给 testtools.run。

python -m testtools.run discover --load-list my-list

无论你在哪里设置你的 pdb.set_trace() 都会进入调试器。

常见问题解答

如何只运行一个测试?只运行一些测试?

要限制运行的测试,请向 tox 提供一个合适的窄正则表达式以限制测试发现

# Run only the tests in the TestAlarms and TestDeprecatedPipeline classes
 tox -epy27 --  '(TestAlarms|TestDeprecatedPipeline)'


要运行一个测试

source .tox/py27/bin/activate
python -m testtools.run <test>

如何在第一次失败后退出测试运行?

有时你想运行所有测试,但在第一次失败后退出(而不是等到结束)。在堆栈底部的 subunit.run 作为测试运行器 的项目中,可以通过直接使用 testr 并跳过 tox 来实现。

# warm up the virtualenv
source .tox/py27/bin/activate
# start the tests with -f
testr run -- -f


在某些环境中(例如 Ceilometer),有必要建立测试环境

# warm up the virtualenv
source .tox/py27/bin/activate
# start the tests with -f in the right environment
./setup-test-env.sh testr run -- -f

当输出中看到“测试运行实际上没有运行任何测试”时,我该怎么办?

当在测试列出过程中遇到错误(例如导入错误)时,可能会发生这种情况。

Non-zero exit code (2) from test listing.
error: testr failed (3)
The test run didn't actually run any tests


要查看跟踪,请列出测试

source .tox/py27/bin/activate
testr list-tests