python - 如何编写分两个阶段运行的pytest测试,每个阶段按顺序运行?
问题描述
我在 pytest 中编写了一堆测试,其中许多采用以下形式(伪代码):
def test1(self, ...):
expected_events = do_thing1_that_should_generate_events(...)
assert wait_for_events_to_appear_in_ui(expected_events)
事件需要几分钟才能出现在 UI 中,因此会在 UI 中wait_for_events_to_appear_in_ui
轮询它们,并设置超时。这行得通,但是每个这样的测试都会运行几分钟,所以总运行时间会很长。
所以,我想先运行所有的do_thingX
动作,然后运行所有的验证。我考虑将预期的事件添加到某个列表中,并进行最终测试来验证所有这些事件 - 但这意味着如果do_thing1
,pytest 不会报告test1
失败,而是最终测试 - 这是次优的。
理想情况下,测试看起来像:
def test1(self, ...):
expected_events = do_thing1_that_should_generate_events(...)
# some kind of magic that works like yield?
assert wait_for_events_to_appear_in_ui(expected_events)
我怎样才能做到这一点?
解决方案
首先看一下pytest-xdist,它用于在多个进程之间进行并行测试等。不过,我不知道这对您的情况有多好。请继续阅读以获取更具体的解决方案。
您需要在问题中暗示的单个测试函数中管理这些测试的异步运行。也许你使用同步代码,也许你使用异步框架;这与此正交。我将假设您可以自己管理它,并且无论如何它都不是特定于 pytest 的东西。
要解决一个 pytest 测试函数中一揽子通过/失败的问题,您需要子测试。pytest-subtestssubtests
允许您通过提供一个夹具(它也支持subTest()
from )在单个测试函数中编写子测试unittest
。
这是提供的示例:
def test(subtests):
for i in range(5):
with subtests.test(msg="custom message", i=i):
assert i % 2 == 0
pytest的输出:
λ pytest .tmp\test-subtest.py
======================== test session starts ========================
...
collected 1 item
.tmp\test-subtest.py .F.F.. [100%]
============================= FAILURES ==============================
____________________ test [custom message] (i=1) ____________________
def test(subtests):
for i in range(5):
with subtests.test(msg='custom message', i=i):
> assert i % 2 == 0
E assert (1 % 2) == 0
.tmp\test-subtest.py:4: AssertionError
____________________ test [custom message] (i=3) ____________________
def test(subtests):
for i in range(5):
with subtests.test(msg='custom message', i=i):
> assert i % 2 == 0
E assert (3 % 2) == 0
.tmp\test-subtest.py:4: AssertionError
================ 2 failed, 1 passed in 0.07 seconds =================
乍一看,失败/通过的数字有点违反直觉。看起来我们有五个子测试,其中两个应该失败;事实上,我们报告了两次失败。但是我们只有一个通过测试,而不是三个。那一关就是test_func()
它自己;由于该with
块正在捕获内部的断言,test_func()
因此不会失败。其他三个子测试没有失败,因此根本没有报告——尽管我们确实看到它们出现在进度点中。
总而言之:自己管理测试,并使用pytest-subtests获取单独的失败报告。
推荐阅读
- eclipse - Eclipse(Oxygen)可以自动查找项目中的所有头文件吗?
- python - tf.image.random_flip_left_right() 将多个图像放在一起
- dbscan - Dbscan 密度连通性
- iphone - iPhone的TCP客户端连接超时但在Xcode模拟器中有效
- c - 如何使除数上的结果不四舍五入?
- algorithm - 字谜算法
- javascript - jQuery 根据 RADIO BUTTON 更改 FIELDSET
- c++ - 接受来自用户输入的 5 个数字并输出最大和最小的
- c# - 通过保持异步将对象分配给对象任务内的某个值
- javascript - 通过 for 循环向元素添加事件会导致所有元素仅影响循环中的最后一个元素