pytest fixture of fixtures

后端 未结 2 2007
日久生厌
日久生厌 2020-12-17 02:07

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:

File

相关标签:
2条回答
  • 2020-12-17 02:39

    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):
        ...
    

    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.

    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.

    Documentation of plugin pytest-data: http://horejsek.github.io/python-pytest-data/

    0 讨论(0)
  • 2020-12-17 03:04

    One solution I found is to abuse the test cases as following:

    from test_for_class_a import *
    from test_for_class_b import *
    from test_for_class_c import *
    
    list_of_all_fixtures = []
    
    
    # This will force pytest to generate all sub-fixture for class a
    @pytest.mark.usefixtures(setup_class_a)
    def test_register_class_a_fixtures(setup_class_a)
        list_of_fixtures.append(setup_class_a)
    
    
    # This will force pytest to generate all sub-fixture for class b
    @pytest.mark.usefixtures(setup_class_b)
    def test_register_class_b_fixtures(setup_class_b)
        list_of_fixtures.append(setup_class_b)
    
    
    # This will force pytest to generate all sub-fixture for class c
    @pytest.mark.usefixtures(setup_class_c)
    def test_register_class_b_fixtures(setup_class_c)
        list_of_fixtures.append(setup_class_c)
    
    
    # This is the real test to apply on all fixtures
    def test_all_fixtures():
        for my_fixture in list_of_all_fixtures:
            # do something with my_fixture
    

    This implicitly rely on the fact that all test_all_fixture is executed after all the test_register_class*. It is obviously quite dirty but it works...

    0 讨论(0)
提交回复
热议问题