【问题标题】:How to keep Unit tests and Integrations tests separate in pytest如何在 pytest 中保持单元测试和集成测试分开
【发布时间】:2019-07-20 18:25:56
【问题描述】:

根据Wikipedia 和各种articles,最好将测试分为单元测试(首先运行)和集成测试(第二次运行),其中单元测试通常非常快,并且应该在每次构建时运行CI 环境,但是集成测试需要更长的时间才能运行,并且应该更多地每天运行。

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

在尝试将测试分为这些类别时,我这样做是否正确?有没有一个很好的例子可以做到这一点?

【问题讨论】:

    标签: python unit-testing testing integration-testing pytest


    【解决方案1】:

    是的,您可以使用 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 装饰你的单元测试,但我觉得这有点乏味/冗长)

    请参阅documentation 了解更多信息。

    【讨论】:

    • 啊,这看起来很完美,马库斯!您是否同意将测试划分为单元和集成对于使用 pytest 的 python 项目是一个好主意?你就是这样做的吗?
    • @Harlekuin 如果您的意思是元数据允许它们单独运行,当然;我也面临着需要很长时间才能运行的大规模测试(和基准测试)的问题。如果您指的是目录,我会说这实际上取决于项目和测试的性质。希望我能帮上忙!
    • 你确实帮助了马库斯,我真的很感激
    • 请注意,“integtest”等自定义标记应注册到 pytest.ini 文件中(参见documentation),否则会引发警告
    • 将单元测试和集成测试放在同一个文件中并不是一个好主意。理想情况下,它们应该位于单独的文件夹结构中(如另一个答案中所述)
    【解决方案2】:

    您还可以将单元和集成测试在结构上分开到特定目录中。这是来自 A. Shaw 的 article 的示例文件结构Python 测试入门

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

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

    示例

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

    使用标准库中的unittest

    λ python -m unittest discover -s tests/integration
    

    nose:

    λ nose tests/integration
    

    pytest:

    λ pytest tests/integration
    

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

    λ cd <root_dir>
    λ pytest project/
    

    【讨论】:

    • 很好,我喜欢不受特定测试运行器约束的想法。如果您刚刚通过父“tests”文件夹,大多数测试运行程序是否能够同时发现单元和集成?
    • 可能。我仍然使用旧的nose 测试运行器,它也可以处理这种发现。请查阅每个库的文档,因为命令行调用会有所不同。
    • 我现在可以确认pytest 也有auto test-discovery
    • 这样分离时,也可以在单元测试后运行pytest tests/unit tests/integration进行集成测试。
    • 在这种情况下,你将如何在 tests/unit/test_helloworld 中导入 my_app/helloworld.py。我正在尝试遵循此目录结构,但导入似乎无法为我解决。
    猜你喜欢
    • 2010-10-23
    • 2012-01-01
    • 2014-11-15
    • 1970-01-01
    • 2011-02-06
    • 2016-01-23
    • 2016-10-03
    • 2014-12-28
    • 1970-01-01
    相关资源
    最近更新 更多