跳转到主要内容

通过一些控制随机性来随机化pytest测试的执行顺序

项目描述

https://img.shields.io/badge/python-3.7%2C%203.8%2C%203.9%2C%203.10-blue.svg

pytest-random-order 是一个 pytest 插件,用于随机化测试的执行顺序。这可以用来检测一个测试只是因为恰好在一个使系统处于 有利 状态的不相关测试之后运行而通过。

此插件允许用户控制他们想要引入的随机程度,并可以禁用测试子集的重新排序。可以通过传递在先前测试运行中报告的种子值来按特定顺序重新运行测试。

https://raw.githubusercontent.com/jbasko/pytest-random-order/master/docs/pytest-random-order-design.png

快速开始

安装

$ pip install pytest-random-order

从v1.0.0版本开始,此插件默认不再随机测试。要启用随机化,您必须以以下方式之一运行pytest

pytest --random-order
pytest --random-order-bucket=<bucket_type>
pytest --random-order-seed=<seed>

如果您希望始终随机化测试顺序,请配置pytest。有许多方法可以实现,我最喜欢的一种是在pytest选项下的项目特定配置文件中添加 addopts = --random-order(通常在 [pytest][tool:pytest] 节中)。

或者,您可以设置环境变量 PYTEST_ADDOPTS

export PYTEST_ADDOPTS="--random-order"

要随机化模块内的测试顺序并打乱测试模块的顺序(这是插件的默认行为),请按以下方式运行pytest

$ pytest --random-order

要更改重新排序的范围,请使用 --random-order-bucket=<bucket-type> 选项运行pytest,其中 <bucket-type> 可以是 classmodulepackageglobal

$ pytest -v --random-order-bucket=package

要禁用模块或类中的测试重新排序,请使用pytest标记符号

pytestmark = pytest.mark.random_order(disabled=True)

要按照特定顺序重新运行测试

$ pytest -v --random-order-seed=<seed>

所有启用随机化的运行都会报告种子值,如果您遇到导致问题的特定测试顺序,您可以在测试报告中查找该值并使用上述命令重复运行。

platform darwin -- Python 3.5.6, pytest-3.9.1, py-1.7.0, pluggy-0.8.0
Using --random-order-bucket=module
Using --random-order-seed=383013

设计

https://raw.githubusercontent.com/jbasko/pytest-random-order/master/docs/pytest-random-order-design.png

该插件将测试分组到桶中,然后在桶内打乱顺序,最后打乱桶。

给定上述测试套件,以下是几个可能生成的测试顺序之一

https://raw.githubusercontent.com/jbasko/pytest-random-order/master/docs/pytest-random-order-example1.png https://raw.githubusercontent.com/jbasko/pytest-random-order/master/docs/pytest-random-order-example2.png

您可以选择几种桶类型

测试将在类内部打乱顺序,并且类将被打乱,但一个类中的测试永远不会在其他类或模块的测试之间运行。

模块

与上面相同,但在模块级别。如果您仅使用 --random-order 标志或 --random-order-seed=<seed> 运行pytest,则应用此设置。

与上面相同,但在包级别。请注意,属于包 x.y.z 的模块(以及那些模块中的测试)不属于包 x.y,因此在使用 package 桶类型进行随机化时,它们将落在不同的桶中。

父项

如果您使用不属于任何模块的自定义测试项,您可以使用此选项将测试项的重新排序限制在其所属的 父项 内。对于常规测试函数,父项是它们声明的模块。

祖父项

与上述 父项 类似,但使用测试项的祖父项作为桶键。

全局

所有测试都落在同一个桶中,完全随机,测试可能需要更长时间运行。

无(已弃用)

禁用打乱。 自1.0.4版起已弃用,因为此插件默认不再打乱测试,因此没有可禁用的内容。

如果您有三个测试桶 ABC,其中每个桶包含三个测试 12,以及 3,那么非全局随机化可能产生的许多潜在顺序之一可以是

c2, c1, c3, a3, a1, a2, b3, b2, b1

如您所见,所有C测试都“紧挨着”彼此执行,A和B桶中的测试也是如此。任何桶X中的测试都保证不会与另一个桶Y中的测试交织在一起。例如,如果您选择module类型的桶,则桶X包含此模块中所有测试。

默认情况下,当启用随机化时,您的测试将在module级别进行随机化,这意味着单个模块X内的测试将按无特定顺序执行,但其他模块的测试不会在模块X的测试之间混合。

无论选择的桶类型如何,都可以按模块或类禁用随机重排。

用法和技巧

桶类型选择

最好从最小的桶类型(classmodule,取决于您是否有基于类的测试)开始,当您确信您的测试可以处理它时再切换到更大的桶类型。

如果您的测试依赖于模块或会话作用域的设置,更多的测试随机顺序将意味着测试速度变慢。在编码时,您可能不想在globalpackage级别进行随机化,而需要快速确认没有出现重大问题。

在模块或类中禁用洗牌

您可以通过标记模块或类为random_order并传递disabled=True来禁用单个模块或类内测试的洗牌。

pytestmark = pytest.mark.random_order(disabled=True)

def test_number_one():
    assert True

def test_number_two():
    assert True
class MyTest(TestCase):
    pytestmark = pytest.mark.random_order(disabled=True)

    def test_number_one(self):
        self.assertTrue(True)

无论测试运行的桶类型如何,test_number_one都将始终在test_number_two之前运行。

按相同顺序重新运行测试(相同种子)

如果您发现测试失败是因为您重新排列了测试,您可能希望能够按相同的失败顺序重新运行测试。为了允许重现测试顺序,插件会报告它用于伪随机数生成器的种子值。

============================= test session starts ==============================
..
Using --random-order-bucket=module
Using --random-order-seed=24775
...

现在,您可以使用--random-order-seed=...作为下一次运行的参数来产生相同的顺序。

$ pytest -v --random-order-seed=24775

首先运行上次失败的测试

从v0.8.0开始,pytest缓存插件的--failed-first标志已支持——上次运行中失败的测试将在通过洗牌桶类型之前运行。

禁用插件

如果插件表现不佳或您只想确保它不是导致您的测试失败或不应该通过的原因,您可以禁用它。

$ pytest -p no:random_order

请注意,默认情况下禁用随机化。通过传递-p no:random_order,您将停止插件注册,因此它的钩子不会注册,其命令行选项也不会出现在--help中。

变更日志

v1.1.1 (2024-01-20)

  • 修复了#54 - 在禁用cacheprovider插件时出现AttributeError。感谢@jhanm12。

v1.1.0 (2022-12-03)

  • 修复了xdist支持(感谢@matejsp)。

v1.0.4 (2018-11-30)

  • 修复了在#36中报告的doctests问题 - classpackagemodule未工作,因为DoctestItem没有clsmodule属性。感谢@tobywf。

  • 弃用none桶类型。

  • 使用tox运行pytest-random-order的测试,包括pytest 3和4。

v1.0.3 (2018-11-16)

  • 修复了与pytest 4.0.0的兼容性问题,如先前一样与pytest 3.0+兼容。

  • 源分布中包含测试。

v1.0.0 (2018-10-20)

  • 插件默认不再更改测试顺序。您必须执行以下操作之一:1) 传递 --random-order,或 --random-order-bucket=<bucket>,或 --random-order-seed=<seed>,或 2) 编辑您的 pytest 配置文件,并在 addopts 下添加这些选项之一,或 3) 在环境变量 PYTEST_ADDOPTS 中指定这些标志。

  • 需要 Python 3.5+。如果您想使用此插件与 Python 2.7 一起使用,请使用稳定的 v0.8.0 版本,如果您对默认随机化测试顺序满意,则这是一个很好的选择。

  • 插件注册的名称已从 random-order(连字符)更改为 random_order(下划线)。这解决了通过标准 -p 标志禁用或启用此插件时的一致性问题。以前,可以通过传递 -p no:random-order 来禁用插件,但只能通过传递 -p pytest_random_order.plugin 来重新启用。现在,它们是 -p no:random_order 来禁用和 -p random_order.plugin 来启用(我认为 .plugin 部分,因为 pytest 可能认为它与 random_order 无关,并导入它,而没有它就是同一件事,所以不导入它))。

v0.8.0

  • pytest 缓存插件的 --failed-first 现在正常工作。

致谢

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。

源分布

pytest-random-order-1.1.1.tar.gz (14.6 kB 查看散列)

上传时间

构建分布

pytest_random_order-1.1.1-py3-none-any.whl (11.5 kB 查看散列)

上传时间 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面