使用pytest时如何组织几个测试函数的步骤?
How to organize steps from several test functions when using pytest?
我有三个测试用例,其中两个对第三个有一定的依赖性。也就是说,测试 test_inner_1
和 test_inner_2
彼此独立,但如果 test_outher
失败,它们的执行就没有意义。如果测试 test_outher
通过,它们都应该是 运行,如果 test_outher
失败,它们都应该被跳过。
pytest
手册https://pytest.org/latest/example/simple.html
展示了一些简单的例子,如何实现增量测试
测试步骤。我正在尝试将这种方法应用于我的情况并且
实现类似的东西:
conftest.py的内容:
import pytest
def pytest_runtest_makereport(item, call):
if "incremental" in item.keywords:
if call.excinfo is not None:
parent = item.parent
parent._previousfailed = item
def pytest_runtest_setup(item):
if "incremental" in item.keywords:
previousfailed = getattr(item.parent, "_previousfailed", None)
if previousfailed is not None:
pytest.xfail("previous test failed (%s)" % previousfailed.name)
test_example.py的内容:
import pytest
@pytest.mark.incremental
class TestUserHandling:
def test_outher(self):
assert 0
class TestInner:
def test_inner_1(self):
assert 0
def test_inner_2(self):
pass
不幸的是,我得到了输出
==================== 2 failed, 1 passed in 0.03 seconds ====================
同时期望获得输出
=================== 1 failed, 2 xfailed in 0.03 seconds ====================
如何更正 conftest.py
以获得所需的行为?
有一个名为 pytest-dependency 的 pytest 插件可以在这种情况下执行您想要执行的操作。
您的代码可以如下所示:
import pytest
import pytest_dependency
@pytest.mark.dependency()
def test_outher():
assert 0
@pytest.mark.dependency(depends=["test_outher"])
def test_inner_1():
assert 0
@pytest.mark.dependency(depends=["test_outher"])
def test_inner_2():
pass
输出为:
=================================== FAILURES ===================================
_________________________________ test_outher __________________________________
@pytest.mark.dependency()
def test_outher():
> assert 0
E assert 0
test_example.py:6: AssertionError
===================== 1 failed, 2 skipped in 0.02 seconds ======================
你当然可以使用类,但对于这个例子来说没有必要。如果您需要 类 的示例,请告诉我。
您还可以使用 pytest-steps 创建一个包含您的测试的测试套件并声明依赖关系,它的行为方式相同(如果 outher 失败则跳过 inner1 和 inner2):
编辑:新的生成器模式使它更容易:
from pytest_steps import test_steps, optional_step
@test_steps('step_outher', 'step_inner_1', 'step_inner_2')
def test_suite():
# Step outher
assert 1
yield
# Step inner 1
with optional_step('step_inner_1') as step_inner_1:
assert 0
yield step_inner_1
# Step inner 2
with optional_step('step_inner_2') as step_inner_2:
assert 0
yield step_inner_2
旧答案:
from pytest_steps import test_steps, depends_on
def step_outher():
assert 0
@depends_on(step_outher)
def step_inner_1():
assert 0
@depends_on(step_outher)
def step_inner_2():
pass
@test_steps(step_outher, step_inner_1, step_inner_2)
def test_suite(test_step):
# Execute the step
test_step()
您还可以使用它在测试步骤之间共享中间结果,有关详细信息,请参阅文档。 (顺便说一句,我是作者 :) )
我有三个测试用例,其中两个对第三个有一定的依赖性。也就是说,测试 test_inner_1
和 test_inner_2
彼此独立,但如果 test_outher
失败,它们的执行就没有意义。如果测试 test_outher
通过,它们都应该是 运行,如果 test_outher
失败,它们都应该被跳过。
pytest
手册https://pytest.org/latest/example/simple.html
展示了一些简单的例子,如何实现增量测试
测试步骤。我正在尝试将这种方法应用于我的情况并且
实现类似的东西:
conftest.py的内容:
import pytest
def pytest_runtest_makereport(item, call):
if "incremental" in item.keywords:
if call.excinfo is not None:
parent = item.parent
parent._previousfailed = item
def pytest_runtest_setup(item):
if "incremental" in item.keywords:
previousfailed = getattr(item.parent, "_previousfailed", None)
if previousfailed is not None:
pytest.xfail("previous test failed (%s)" % previousfailed.name)
test_example.py的内容:
import pytest
@pytest.mark.incremental
class TestUserHandling:
def test_outher(self):
assert 0
class TestInner:
def test_inner_1(self):
assert 0
def test_inner_2(self):
pass
不幸的是,我得到了输出
==================== 2 failed, 1 passed in 0.03 seconds ====================
同时期望获得输出
=================== 1 failed, 2 xfailed in 0.03 seconds ====================
如何更正 conftest.py
以获得所需的行为?
有一个名为 pytest-dependency 的 pytest 插件可以在这种情况下执行您想要执行的操作。
您的代码可以如下所示:
import pytest
import pytest_dependency
@pytest.mark.dependency()
def test_outher():
assert 0
@pytest.mark.dependency(depends=["test_outher"])
def test_inner_1():
assert 0
@pytest.mark.dependency(depends=["test_outher"])
def test_inner_2():
pass
输出为:
=================================== FAILURES ===================================
_________________________________ test_outher __________________________________
@pytest.mark.dependency()
def test_outher():
> assert 0
E assert 0
test_example.py:6: AssertionError
===================== 1 failed, 2 skipped in 0.02 seconds ======================
你当然可以使用类,但对于这个例子来说没有必要。如果您需要 类 的示例,请告诉我。
您还可以使用 pytest-steps 创建一个包含您的测试的测试套件并声明依赖关系,它的行为方式相同(如果 outher 失败则跳过 inner1 和 inner2):
编辑:新的生成器模式使它更容易:
from pytest_steps import test_steps, optional_step
@test_steps('step_outher', 'step_inner_1', 'step_inner_2')
def test_suite():
# Step outher
assert 1
yield
# Step inner 1
with optional_step('step_inner_1') as step_inner_1:
assert 0
yield step_inner_1
# Step inner 2
with optional_step('step_inner_2') as step_inner_2:
assert 0
yield step_inner_2
旧答案:
from pytest_steps import test_steps, depends_on
def step_outher():
assert 0
@depends_on(step_outher)
def step_inner_1():
assert 0
@depends_on(step_outher)
def step_inner_2():
pass
@test_steps(step_outher, step_inner_1, step_inner_2)
def test_suite(test_step):
# Execute the step
test_step()
您还可以使用它在测试步骤之间共享中间结果,有关详细信息,请参阅文档。 (顺便说一句,我是作者 :) )