我确实有一些更复杂的项目,如果您运行pytest --collect-only
,您将最终因发现的测试文件导致导入失败而导致导入失败。
我想更改这些测试文件,以使其在收集时不会失败。
这是因为用户可能希望使用pytest -k foo
之类的特定模式运行测试,但是如果不相关的测试收集失败,他将无法执行此操作。
我知道我可以定义一个pytest_configure
方法,该方法称为durind集合,但是如果我将导入移入其中,那么当解释器到达尝试使用缺少的导入的代码时,仍然会失败。 / p>
def pytest_configure(config):
try:
import foo
except:
pytest.skip("skipping when foo is not installed")
def test_foo()
assert foo.is_enabled() # <-- foo is undefined here
我的示例显然过度仿真,因为我们都知道我可以在测试方法中再次添加导入,但是我不想在数十种方法中这样做。我正在寻找更清洁的解决方案。
答案 0 :(得分:1)
如果您不想因导入(或任何其他)错误而中止测试集合,请使用--continue-on-collection-errors
标志。示例:
test_spam.py
的导入未解决:
import foo
def test_foo():
assert foo.is_enabled()
test_eggs.py
是可运行的:
def test_bar():
assert True
运行测试会得到:
$ pytest --continue-on-collection-errors -v
======================================= test session starts =======================================
...
collected 1 item / 1 errors
test_eggs.py::test_bar PASSED
============================================= ERRORS ==============================================
__________________________________ ERROR collecting test_spam.py __________________________________
ImportError while importing test module '/home/hoefling/projects/private/stackoverflow/so-56997157/test_spam.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
test_spam.py:2: in <module>
import foo
E ModuleNotFoundError: No module named 'foo'
================================ 1 passed, 1 error in 0.06 seconds ================================
这将指示pytest
运行它可以收集的所有测试(在此示例中为test_eggs::test_bar
),但是由于无法收集一个模块而使执行失败。如果您不想失败,请使用pytest
提供便捷的importorskip
函数:
import pytest
foo = pytest.importorskip('foo')
def test_foo():
assert foo.is_enabled()
现在运行测试将产生:
$ pytest -v
======================================= test session starts =======================================
...
collected 1 item / 1 skipped
test_eggs.py::test_bar PASSED [100%]
=============================== 1 passed, 1 skipped in 0.04 seconds ===============================
如您所见,这两者之间的区别在于对收集错误的处理(1 errors
与1 skipped
)以及最终的退出代码(1与0)。
就我个人而言,我倾向于不使用importorskip
,因为它可能导致长期不执行测试。如果您有大型测试套件,通常只需简要查看测试结果(失败/未失败),而不必显式检查是否有新的跳过的测试。这可能导致以下情况:测试没有在任何地方(甚至没有在CI服务器上)执行,直到有人注意到它(最佳情况),或者(最坏情况)假设被测试的代码在生产系统上显示错误。当然,还有其他一些指标可以间接地保护该情况(例如,注意测试范围并禁止降低测试范围的提交),但是IMO的显式失败设置了一个巨大的感叹号,您无法避免。 >