运行 仅测试依赖于更改的

Run only tests which depend on the change

如何检测 pytest 需要进行哪些测试运行?

到目前为止,我 运行 在 CI 中进行了所有测试。这很慢。

有没有办法自动检测哪些测试需要 运行,并且只执行整个测试套件的一小部分?

背景:我正在阅读 Google SE 的书并了解他们巨大的 monorepo 以及他们的工具 Blaze 可以检测哪些测试需要 运行。听起来很酷。

您可以将 @pytest.mark 添加到测试中

@pytest.mark.SomeFeature
@pytest.mark.Regression
def test_example1(self):
    pass

@pytest.mark.AnotherFeature
@pytest.mark.Regression
def test_example2(self):
    pass

并在触发测试时使用它

pytest TestsFolder -m SomeFeature

这将 运行 仅 test_example1-m Regression 将 运行 两项测试。

您可以为此使用 pytest-incremental 插件,它使用 AST 来分析项目的导入结构,并且只运行源代码已更改的测试。

pip install pytest-incremental
python -m pytest --inc

Analyzing the graph is easy to see that a change in app would cause only test_app to be execute. And a change in util would cause all tests to be executed.

from the docs

我对 testmon 文档的 pytest-testmon which determines the subset of tests to execute on code change based on test coverage. The details on that are explained well in Determining affected tests 部分有很好的经验,但一般建议是保持高 line/branch 覆盖率以使 testmon 有效。这也意味着它将在 coverage 失败的地方失败。

如果你想在 CI 中使用它,你需要在测试作业之间缓存 .testmondata 数据库文件,并确保在调用 [=17] 时使用 --testmon arg =].它还取决于您的 CI 提供商,但大多数流行的提供缓存机制(Github、Gitlab、CircleCI、Appveyor 等)。

testmon 也可以有效地与 pytest-watch watchdog 结合,以保持一个守护进程来执行测试 运行。重新运行代码更改测试子集并在成功或失败时发送系统通知的示例命令:

$ pytest-watch --runner="pytest --testmon" \
  --onfail="notify-send --urgency=low -i error 'Tests Failed'" \
  --onpass="notify-send --urgency=low -i info 'Tests passed'"

您也可以使用 Bazel 进行构建和测试;然而,在我看来,对于一个纯粹的 Python 项目来说,这是一种矫枉过正的做法,仅出于增量测试目的是不值得的。