如何为测试功能的参数化提供夹具产生的数据?如果不行的话还有其他办法吗?

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

我需要创建多个用户(通过发送 HTTP 请求)并使用创建的用户数据(登录名、密码)运行登录页面测试

我有固定装置,它生成用户并提供他们的登录数据(yield 中的 [(login1,password1),(login2,password2)] 等元组列表。我想使用此yield 数据作为参数化,因为我只知道一个正确的使用不同的测试数据多次运行 1 个测试的方法。

代码如下:

conftest.py

@pytest.fixture(scope="session", autouse=True)
def test_user_fixture():
    print("INFO | Generating test user data")
    user_data_set = user_data_generator()
    login_data = []

    for user_data in user_data_set:
        login_data.append((user_data[0], user_data[1]))
        if send_user_create_request(user_data) != 200: # this function sends request to create user AND returns status_code
            pytest.exit("ERROR | Test user wasn't created")

    yield login_data

    print("INFO | Clearing test data")

test_login_page.py

@pytest.mark.usefixtures('webdriver_fixture', 'test_user_fixture')
class TestPositiveLogin:

    @pytest.mark.parametrize("login, password", test_user_fixture)
    def test_positive_login(self, webdriver_fixture, login, password):
        driver = webdriver_fixture
        page = BasePage(driver)
        page.open_base_page()
        page.login(login, password)

这里我尝试只使用fuxture作为参数,因为login_data完全适合参数数据格式,但python说

名称错误:名称“test_user_fixture”未定义

你能帮我解决这个问题或者给出另一个解决方案吗

python pytest fixtures parametrized-testing
1个回答
0
投票

您当前的

test_user_fixture
装置返回登录名/密码列表。我确信您正在使用
yield
,因为您希望稍后进行一些清理(例如删除用户)。

我的建议是

test_user_fixture
仅返回单个登录名/密码。然后我们可以使用
params=
关键字来参数化这个夹具:

# conftest.py
import logging

import pytest

def user_data_generator():
    """Mocked"""
    return [
        ("user1", "password1"),
        ("user2", "password2"),
    ]

USERS_DATA = list(user_data_generator())

def test_id(user_data):
    """Given (login, password), return the login part.

    We use this login as part of the test ID
    """
    return user_data[0]


@pytest.fixture(scope="session", autouse=True, params=USERS_DATA, ids=test_id)
def test_user_fixture(request):
    login, password = request.param[:2]
    logging.debug("In test_user_fixture, login=%r, password=%r", login, password)

    if send_user_create_request((login, password)) != 200:
        pytest.exit("ERROR | Test user wasn't created")
    yield login, password

    logging.info("Clearing test data")

# test_login_page.py
import logging


class TestPositiveLogin:
    def test_positive_login(self, webdriver_fixture, test_user_fixture):
        login, password = test_user_fixture
        logging.debug("webdriver_fixture=%r", webdriver_fixture)
        logging.debug("login=%r", login)
        logging.debug("password=%r", password)

# pyproject.toml
[tool.pytest.ini_options]
log_cli="true"
log_level="DEBUG"

log_cli="false"
时输出:

test_login_page.py::TestPositiveLogin::test_positive_login[user1] PASSED
test_login_page.py::TestPositiveLogin::test_positive_login[user2] PASSED

log_cli="true"
时输出:


test_login_page.py::TestPositiveLogin::test_positive_login[user1]
---------------------------------------------------------------------- live log setup ----------------------------------------------------------------------
DEBUG    root:conftest.py:26 In test_user_fixture, login='user1', password='password1'
---------------------------------------------------------------------- live log call -----------------------------------------------------------------------
DEBUG    root:test_login_page.py:8 webdriver_fixture='Mocked WebDriver'
DEBUG    root:test_login_page.py:9 login='user1'
DEBUG    root:test_login_page.py:10 password='password1'
PASSED
test_login_page.py::TestPositiveLogin::test_positive_login[user2]
---------------------------------------------------------------------- live log setup ----------------------------------------------------------------------
INFO     root:conftest.py:32 Clearing test data for login='user1'
DEBUG    root:conftest.py:26 In test_user_fixture, login='user2', password='password2'
---------------------------------------------------------------------- live log call -----------------------------------------------------------------------
DEBUG    root:test_login_page.py:8 webdriver_fixture='Mocked WebDriver'
DEBUG    root:test_login_page.py:9 login='user2'
DEBUG    root:test_login_page.py:10 password='password2'
PASSED
-------------------------------------------------------------------- live log teardown ---------------------------------------------------------------------
INFO     root:conftest.py:32 Clearing test data for login='user2'

注释

  • 我假设 USERS_DATA 包含

    [(user, password, ...), ...]

  • params=USERS_DATA
    对夹具进行参数化。即使此装置的作用域为会话级别,它也会为
    USERS_DATA
    中的每个元素调用一次。换句话说,如果
    USERS_DATA
    包含 2 个元素,则该夹具将被调用两次。

  • test_id()
    函数从测试参数中提取
    login
    ,从而提供更好的方法来识别测试。

  • test_user_fixture
    返回一个
    (login, password)
    的元组,因此在测试中,我们将其解压以使其更容易:

      login, password = test_user_fixture
    
  • 我更喜欢使用

    logging
    而不是
    print
    ,因为我可以通过
    pyproject.toml
    中的这条线打开/关闭:

      log_cli="true"
    

    只需将

    true
    替换为
    false
    ,我就可以有效地关闭所有日志记录。我还可以使用此行控制日志级别(例如 WARN、INFO、DEBUG...):

      log_level="DEBUG"
    
© www.soinside.com 2019 - 2024. All rights reserved.