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

Har*_*uin 8 python testing integration-testing unit-testing pytest

根据Wikipedia和各种文章的介绍,最佳实践是将测试分为单元测试(首先运行)和集成测试(第二次运行),在这些测试中,单元测试通常非常快,应该在CI环境中的每个构建中都运行,但是集成测试运行时间更长,应该每天运行更多。

有没有办法在pytest中划分这些?大多数项目似乎没有多个测试文件夹,因此有没有一种方法可以确保我仅根据情况(CI与每日构建)运行单元和/或集成?在计算测试覆盖率时,我假设我必须同时运行两者。

在尝试将测试划分为这些类别时,我会采用正确的方法吗?在执行此操作的项目中是否有很好的例子?

pyl*_*ang 33

您还可以在结构上将单元测试和集成测试分离到特定目录中。以下是 A. Shaw 的文章 Getting Started With Testing in Python 中的示例文件结构:

在此处输入图片说明

通过结构化方法,您可以:

  1. 不需要用属性或@pytest.mark.
  2. 不限于特定的测试运行器。请参阅下面的示例。

例子

在这里,我们单独在集成测试上运行各种测试运行器。参见project/上图中的示例目录。

随着unittest从标准库:

? python -m unittest discover -s tests/integration
Run Code Online (Sandbox Code Playgroud)

nose

? nose tests/integration
Run Code Online (Sandbox Code Playgroud)

pytest

? pytest tests/integration
Run Code Online (Sandbox Code Playgroud)

许多测试运行器都有一个自动测试发现机制,可以在子目录中找到测试。这提供了轻松运行所有测试的选择,例如

? cd <root_dir>
? pytest project/
Run Code Online (Sandbox Code Playgroud)

  • 像这样分开时,您还可以运行“pytest测试/单元测试/集成”来在单元测试之后执行集成测试。 (4认同)
  • 很好,我喜欢不绑定到特定测试运行程序的想法。如果您刚刚通过父“tests”文件夹,大多数测试运行者是否能够发现单元和集成? (2认同)
  • 在这种情况下,如何将 my_app/helloworld.py 导入到tests/unit/test_helloworld 中。我试图遵循这个目录结构,但导入似乎无法为我解决。 (2认同)

gmd*_*mds 12

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

例:

def unit_test_1():
    # assert here

def unit_test_2():
    # assert here

@pytest.mark.integtest
def integration_test():
    # assert here
Run Code Online (Sandbox Code Playgroud)

现在,从命令行开始,您只能运行pytest -m "not integtest"单元测试,pytest -m integtest集成测试和普通测试pytest

(您也可以根据需要装饰单元测试pytest.mark.unit,但我发现这有点乏味/冗长)

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

  • 在同一个文件中进行单元测试和集成测试并不是一个好主意。理想情况下,它们应该位于单独的文件夹结构中(如其他答案中所述) (5认同)
  • 请注意,诸如“integtest”之类的自定义标记应注册到 pytest.ini 文件中(请参阅[文档](https://docs.pytest.org/en/stable/example/markers.html#registering-markers)),否则,将会发出警告 (4认同)