夹具的pytest夹具 [英] pytest fixture of fixtures

查看:53
本文介绍了夹具的pytest夹具的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在为一个中型库(约 300 个文件)编写测试.该库中的许多类共享使用 pytest 编码的相同测试方案:

I am currently writing tests for a medium sized library (~300 files). Many classes in this library share the same testing scheme which were coded using pytest:

文件 test_for_class_a.py:

File test_for_class_a.py:

import pytest

@pytest.fixture()
def setup_resource_1():
    ...

@pytest.fixture()
def setup_resource_2():
    ...

@pytest.fixture()
def setup_class_a(setup_resource_1, setup_resource_2):
    ...

def test_1_for_class_a(setup_class_a):
    ...

def test_2_for_class_a(setup_class_a):
    ...

class_b、class_c 等存在类似的文件......唯一的区别是 setup_resource_1 & 的内容.setup_resource_2.

similar files exist for class_b, class_c etc ... The only difference being the content of setup_resource_1 & setup_resource_2.

现在我想重新使用 test_for_class_a.py、test_for_class_b.py 和 test_for_class_c.py 中定义的夹具 setup_class_a、setup_class_b、setup_class_c 来对它们运行测试.

Now I would like to re-use the fixtures setup_class_a, setup_class_b, setup_class_c defined in test_for_class_a.py, test_for_class_b.py and test_for_class_c.py to run tests on them.

在文件 test_all_class.py 中,这有效,但每个测试仅限于一个夹具:

In a file test_all_class.py, this works but it is limited to one fixture per test:

from test_for_class_a import *

@pytest.mark.usefixtures('setup_class_a')      # Fixture was defined in test_for_class_a.py
def test_some_things_on_class_a(request)
    ...

但我正在寻找一种方法来执行更一般的事情:

But I am looking for a way to perform something more general:

from test_for_class_a import *
from test_for_class_b import *   # I can make sure I have no collision here 
from test_for_class_c import *   # I can make sure I have no collision here 

==> @generate_test_for_fixture('setup_class_a', 'setup_class_b', 'setup_class_c') 
def test_some_things_on_all_classes(request)
    ...

有什么办法可以做到这一点吗?我一直在研究工厂的工厂和抽象的 pytest 工厂,但我正在为 pytest 定义夹具的方式而苦苦挣扎.有什么办法可以解决这个问题吗?

Is there any way to do something close to that? I have been looking at factories of factories and abstract pytest factories but I am struggling with the way pytest defines fixture. Is there any way to solve this problems?

推荐答案

我们在工作中遇到了同样的问题,我希望为每个案例只编写一次fixture.所以我写了插件 pytest-data 来做到这一点.示例:

We had same problem at work and I was hoping to write fixture just once for every case. So I wrote plugin pytest-data which does that. Example:

@pytest.fixture
def resource(request):
    resource_data = get_data(reqeust, 'resource_data', {'some': 'data', 'foo': 'foo'})
    return Resource(resource_data)

@use_data(resource_data={'foo': 'bar'})
def test_1_for_class_a(resource):
    ...

@use_data(resource_data={'foo': 'baz'})
def test_2_for_class_a(resource):
    ...

它的优点在于您只需使用一些默认值编写一次设备.当您只需要该装置/资源而您不关心特定设置时,您只需使用它.当您需要测试某些特定属性时,假设要检查该资源是否也可以处理 100 个字符长的值,您可以通过 use_data 装饰器传递它,而不是编写另一个夹具.

What's great about it is that you write fixture just once with some defaults. When you just need that fixture/resource and you don't care about specific setup, you just use it. When you need in test some specific attribute, let's say to check out if that resource can handle also 100 character long value, you can pass it by use_data decorator instead of writing another fixture.

有了它,您就不必关心冲突,因为一切都将只存在一次.然后您可以将 conftest.py 用于您的所有装置,而无需导入测试模块.例如,我们将所有装置的深度模块分开,并全部包含在顶部 conftest.py 中.

With that you don't have to care about conflicts, because everything will be there just once. And then you can use conftest.py for all of your fixtures without importing in test modules. For example we did separate deep module of all fixtures and all included in top conftest.py.

插件文档pytest-data:http://horejsek.github.io/python-pytest-data/

这篇关于夹具的pytest夹具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆