【问题标题】:Pytest fixture with scope “class” doesn't works with "setup_class" method范围为“class”的 Pytest 夹具不适用于“setup_class”方法
【发布时间】:2020-06-09 18:31:20
【问题描述】:

我目前正在使用pytest_addoption 运行我的 API 测试,因此测试应该针对用户在命令行上使用的环境运行。在我的测试文件中,我试图只实例化一次UsersSupport 类,并传递env 参数。我的代码:

conftest.py

import pytest

# Environments
QA1 = 'https://qa1.company.com'
LOCALHOST = 'https://localhost'


def pytest_addoption(parser):
    parser.addoption(
        '--env',
        action='store',
        default='qa1'
    )


@pytest.fixture(scope='class')
def env(request):
    cmd_option = request.config.getoption('env')
    if cmd_option == 'qa1':
        chosen_env = QA1
    elif cmd_option == 'localhost':
        chosen_env = LOCALHOST
    else:
        raise UnboundLocalError('"--env" command line must use "qa1", "localhost"')
    return chosen_env

users_support.py

import requests


class UsersSupport:

    def __init__(self, env):
        self.env = env
        self.users_endpoint = '/api/v1/users'

    def create_user(self, payload):
        response = requests.post(
            url=f'{self.env}{self.users_endpoint}',
            json=payload,
        )
        return response

post_create_user_test.py

import pytest
from faker import Faker
from projects import UsersSupport
from projects import users_payload


class TestCreateUser:

    @pytest.fixture(autouse=True, scope='class')
    def setup_class(self, env):
        self.users_support = UsersSupport(env)
        self.fake = Faker()
        self.create_user_payload = users_payload.create_user_payload

    def test_create_user(self):
        created_user_res = self.users_support.create_user(
            payload=self.create_user_payload
        ).json()
        print(created_user_res)

问题

当我运行pytest projects/tests/post_create_user_test.py --env qa1 时,我收到AttributeError: 'TestCreateUser' object has no attribute 'users_support' 错误,但如果我从setup_class 方法中删除scope,此方法将在每个方法上运行,而不是在所有方法上运行。

如何在setup_class 中使用env 夹具并实例化UsersSupport 类以在所有方法中使用?

【问题讨论】:

  • 你不能把users_support 变成一个类变量吗?
  • @MrBeanBremen 感谢您的回复。即便如此,我还是得到了AttributeError
  • 我在答案中加了一点解释。

标签: python python-3.x pytest


【解决方案1】:

如果您使用具有类作用域的夹具,self 参数不会引用类实例。但是,您仍然可以使用self.__class__ 访问类本身,因此您可以从实例变量中创建类变量。

您的代码可能如下所示:

import pytest
from faker import Faker
from projects import UsersSupport
from projects import users_payload


class TestCreateUser:

    @pytest.fixture(autouse=True, scope='class')
    def setup_class(self, env):
        self.__class__.users_support = UsersSupport(env)
        self.__class__.fake = Faker()
        self.__class__.create_user_payload = users_payload.create_user_payload

    def test_create_user(self):
        created_user_res = self.users_support.create_user(
            payload=self.create_user_payload
        ).json()  # now you access the class variable
        print(created_user_res)

在测试期间,会为每个测试创建一个新的测试实例。
如果你有一个默认的 function 范围的夹具,它将在同一测试实例中调用,因此夹具的 self 参数和当前测试引用同一实例。

class 范围内的夹具的情况下,设置代码在创建测试实例之前在单独的实例中运行 - 这个实例必须一直存在到所有测试结束才能能够执行拆卸代码,因此它与所有测试实例都不同。由于它仍然是同一个测试类的实例,在这种情况下,您可以将变量存储在 测试类 中。

【讨论】:

    猜你喜欢
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 2022-06-12
    • 2022-11-04
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多