如何访问使用 pytest.mark.usefixture 标记传递到 Pytest 类的 Pytest 夹具

问题描述 投票:0回答:1

我编写了一个基本测试类,用于测试所有依赖于不同固定装置的多个视图集,这意味着我不想将固定装置作为参数直接传递到测试类方法中,并且需要将固定装置作为类级别传递对于基测试类的每个子类,但这样做会阻止在类方法中轻松访问固定装置作为类/实例属性。

这是基本测试类的片段

class BaseViewSetTest(TestHelper):
    """
    Base Mixin Test Class to make testing viewset endpoints enjoyable.

    inherit the class in the test class you wish to use for a viewset,
    provide the base_url for the viewset and the create_data needed to
    make a post request to create a data instance linked to the viewset, 
    provide the api_fields list exposed by the serializer of the viewset.
    """
    base_url = ""
    create_data = {}
    api_fields = []

    def test_list_endpoint(self, authenticated_user: tuple[User, APIClient]):
        user, client = authenticated_user
        url = reverse(f"{self.base_url}-list")
        response: Response = client.get(url)
        assert response.status_code == 200
        response_data = response.json()
        # more tests goes here..


@pytest.mark.django_db
@pytest.mark.usefixtures("business")
class TestBusinessViewSet(BaseViewSetTest):
    base_url = "business"
    create_data = {"name": "InfoSec", "email": "[email protected]", "phone_number": "09037637633"}
    api_fields = ["id", "name", "email", "address", "phone_number", "currency"]        

现在我希望能够访问传递到类中的固定装置,以便我可以在基类中操作这些固定装置以更好地设置测试。

例如,我希望能够将夹具实例的用户属性设置为指向当前测试会话的用户属性(用户是夹具数据)。

python-3.x django testing fixtures pytest-django
1个回答
0
投票

我发现传递到 pytest 测试类的固定装置可以通过 pytestmark 实例属性访问,尽管是字符串形式, 将此字符串与请求固定装置结合使用,可以评估实际的固定装置结果(这必须与作为方法参数传递时评估固定装置的方式类似)

注意: 这里选择第一个 pytestmark 项目是非常有意的,可能不适合您,以确保它在使用多个装饰器时将固定装置作为第一个装饰器(最深的装饰器)传递。

class BaseViewSetTest(TestHelper):
    """
    Base Mixin Test Class to make test viewset endpoints enjoyable.

    inherit the class in the test class you wish to use for a viewset
    provide the base_url for the viewset and the create_data needed to
    make a post request to create a data instance linked to the viewset, 
    provide the api_fields exposed by the serializer of the viewset.
    """
    base_url = ""
    create_data = {}
    api_fields = []
    user_related_field = "user"

    @pytest.fixture
    def model_instance(self, request):
        fixture_str = self.pytestmark[0].args[0]
        instance = request.getfixturevalue(f"{fixture_str}")
        return instance

    def test_list_endpoint(self, authenticated_user: tuple[User, APIClient], model_instance):
        user, client = authenticated_user
        # set the current user to be related to the model instance
        setattr(model_instance, self.user_related_field, user)
        model_instance.save()
        url = reverse(f"{self.base_url}-list")
        response: Response = client.get(url)
        assert response.status_code == 200
        response_data = response.json()
        # more tests goes here

@pytest.mark.django_db
@pytest.mark.usefixtures("business")
class TestBusinessViewSet(BaseViewSetTest):
    base_url = "business"
    create_data = {"name": "InfoSec", "email": "[email protected]", "phone_number": "09037637633"}
    api_fields = ["id", "name", "email", "address", "phone_number", "currency"]
    user_related_field = "owner"
        
© www.soinside.com 2019 - 2024. All rights reserved.