【问题标题】:What is a correct approach to manage test data using pytest?使用 pytest 管理测试数据的正确方法是什么?
【发布时间】:2020-07-09 22:31:47
【问题描述】:

我需要为几个相关的应用程序创建自动化测试,并且在测试之间的测试数据管理方面遇到了一个问题。 问题是必须在多个应用程序和/或不同的 API 之间共享相同的数据。 现在我有了 pytest 的下一个结构,它对我很有用,但我怀疑在 conftest.py 中使用测试数据管理是正确的方法:

整体结构如下:

tests/
    conftest.py
    app1/
        conftest.py
        test_1.py
        test_2.py
    app2/
        conftest.py
        test_1.py
        test_2.py
test_data/
    test_data_shared.py
    test_data_app1.py
    test_data_app2.py

这是tests/conftest.py中的测试数据示例:

from test_data.test_data_shared import test_data_generator, default_data

@pytest.fixture
def random_email():
    email = test_data_generator.generate_random_email()
    yield email
    delete_user_by_email(email)

@pytest.fixture()
def sign_up_api_test_data(environment, random_email):
"""
environment is also fixture, capture value from pytest options
"""
    data = {"email": random_email, "other_data": default_data.get_required_data(), "hash": test_data_generator.generate_hash(environment)}
    yield data
    do_some_things_with_data(data)

为此目的使用夹具非常舒适,因为后置条件、范围和其他甜蜜的东西(请注意,应用程序有很多逻辑和关系,所以我不能简单地硬编码数据或将其迁移到 json 文件中) 类似的东西可以在 tests/app1/conftest.py 和 tests/app2/conftest.py 中找到相应的在 app1 和 app 2 中使用的数据。

所以,这里有两个问题: 1. conftest.py 变成了一大堆代码的怪物 2.据我所知,使用 conftest 测试数据是一种不好的方法还是我错了?

提前致谢!

【问题讨论】:

    标签: python testing design-patterns automated-tests pytest


    【解决方案1】:

    我使用 conftest.py 测试数据。
    夹具是向测试提供测试数据的推荐方式。
    conftest.py 是在多个测试文件之间共享夹具的推荐方式。

    至于#2。我觉得用 conftest.py 做测试数据就好了。

    现在对于 #1,“conftest.py 变得太大”。

    特别是对于顶级 conftest.py 文件,在 test/conftest.py,您可以将该内容移动到一个或多个 pytest 插件中。由于 conftest.py 文件可以被认为是“本地插件”,因此将它们转换为插件的过程并不难。

    https://docs.pytest.org/en/latest/writing_plugins.html

    【讨论】:

      【解决方案2】:

      您可能有兴趣查看pytest-cases:它实际上是为解决这个问题而设计的。您会在文档中找到大量示例,并且案例可以位于专用模块、类或测试文件中——这实际上取决于您的需求。例如将两种测试数据生成器放在同一个模块中:

      from pytest_cases import parametrize_with_cases, parametrize
      
      def data_a():
          return 'a'
      
      @parametrize("hello", [True, False])
      def data_b(hello):
          return "hello" if hello else "world"
      
      def user_bob():
          return "bob"
      
      @parametrize_with_cases("data", cases='.', prefix="data_")
      @parametrize_with_cases("user", cases='.', prefix="user_")
      def test_with_data(data, user):
          assert data in ('a', "hello", "world")
          assert user == 'bob'
      

      详情请见documentation。顺便说一句,我是作者;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-12
        • 1970-01-01
        • 2021-03-24
        • 1970-01-01
        • 1970-01-01
        • 2019-01-12
        相关资源
        最近更新 更多