如何在pytest中将单元测试和集成测试分开?

75
根据维基百科和各种文章,将测试分为单元测试(首先运行)和集成测试(其次运行)是最佳实践,其中单元测试通常非常快,并且应在CI环境中每次构建时运行,但是集成测试需要更长时间才能运行,应更多地进行每日运行。
是否有一种方法可以在pytest中划分这些内容?大多数项目似乎没有多个测试文件夹,因此是否有一种方法可以确保根据情况(CI vs每日构建)仅运行单元,集成或两者都运行?计算测试覆盖率时,我假设必须运行两者。
尝试将测试分成这些类别的方式正确吗?是否有一个很好的示例项目已经这样做了?
3个回答

84

你也可以将单元测试和集成测试进行结构分离,并放置在特定的目录中。以下是A. Shaw在articlePython测试入门一文中提供的示例文件结构:

enter image description here

采用结构化方法,您可以:

  1. 无需手动使用属性或@pytest.mark标记各种测试。
  2. 不受特定测试运行器的限制。请参见下面的示例。

示例

这里我们仅对集成测试运行各种测试运行器。请参见上图中的示例 project/ 目录。

使用标准库中的unittest

λ python -m unittest discover -s tests/integration

使用 nose

λ nose tests/integration

使用 pytest
λ pytest tests/integration

tests/ 目录下显式调用测试运行器以运行所有测试:

λ pytest tests/

另外,许多测试运行器都具有自动测试发现机制,可以在子目录中找到测试。

λ cd ..
λ pytest project/

2
很好,我喜欢不受特定测试运行程序限制的想法。如果只传递父级“tests”文件夹,大多数测试运行程序是否能够发现单元测试和集成测试? - Tom Malkin
1
可能。我仍然使用旧的 nose 测试运行器,它也可以处理这种发现。请查阅每个库的文档,因为命令行调用会有所不同。 - pylang
1
我现在可以确认 pytest 也具有自动测试发现功能。 - pylang
8
将其分开后,你也可以运行pytest tests/unit tests/integration来执行单元测试之后再执行集成测试。 - Doopy
2
在这种情况下,你该如何在 tests/unit/test_helloworld 中导入 my_app/helloworld.py?我试图遵循这个目录结构,但是我的导入好像无法解析。 - Rose
显示剩余3条评论

82

是的,您可以使用 pytest.mark 装饰器标记测试。

例如:

def unit_test_1():
    # assert here

def unit_test_2():
    # assert here

@pytest.mark.integtest
def integration_test():
    # assert here

现在,您可以从命令行运行pytest -m "not integtest"来只运行单元测试,pytest -m integtest来只运行集成测试,或者纯粹地运行 pytest 来运行全部测试。

(如果需要的话,您也可以用pytest.mark.unit标记修饰您的单元测试,但我发现这样稍微有点繁琐/冗长)

请参阅文档以获取更多信息。


1
啊,这看起来非常完美,马库斯!你认为将测试分为单元测试和集成测试对于使用pytest的Python项目是个好主意吗?你是这样做的吗? - Tom Malkin
1
@Harlekuin 如果你是指元数据允许它们分别运行,那当然可以;我也面临着大规模测试(和基准测试)需要很长时间才能运行的问题。如果你是指目录方面,我会说这真的取决于项目和测试的性质。希望我有所帮助! - gmds
你肯定帮了马库斯,我非常感激。 - Tom Malkin
4
注意,像“integtest”这样的自定义标记应该被注册到pytest.ini文件中(参见文档)。否则会引发警告。 - yoyoog
5
将单元测试和集成测试放在同一个文件中不是一个好主意。理想情况下,它们应该在一个单独的文件夹结构中(正如其他答案中提到的那样)。 - Harry
为了抑制@yoyoog在pyproject.toml文件中提到的警告,请添加[tool.pytest.ini_options] markers = ["integtest"](包括换行符)。 - JeroenDV

1
截至2022年,另一个选择是pytest-integration包,与仅使用@pytest.mark装饰器相比,它增加了一些额外的功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接