您当前的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"
just replace true
with false
和 I can effectively turn off all logging. I can also control the log level (e.g. WARN, INFO, DEBUG, ...) with this line:
log_level="DEBUG"
Update
如果go 掉ids=
部分,则输出将如下所示:
test_login_page.py::TestPositiveLogin::test_positive_login[test_user_fixture0] PASSED
test_login_page.py::TestPositiveLogin::test_positive_login[test_user_fixture1] PASSED
Notice the part inside the square brackets test_user_fixture0
和 test_user_fixture1
: they are IDs which pytest
generate automatically 和 they are not helpful.
我想要放在这些方括号中的是ID,它们很有用,比如login
.
根据pytest doc的说法,ids=
可能是一系列ID.这意味着以下内容的工作方式相同:
USERS_DATA = list(user_data_generator())
TEST_IDS = [user_data[0] for user_data in USERS_DATA]
@pytest.fixture(
scope="session",
autouse=True,
params=USERS_DATA,
ids=TEST_IDS,
)
def test_user_fixture(request):
...
例如,如果USERS_DATA
是
[
("user1", "password1"),
("user2", "password2"),
]
那么,TEST_IDS
美元将是
[
"user1",
"user2",
]
And these IDs will be used inside of the square brackets. Note that the ids=
can also be a function which take in a single element of the params=
parameter 和 return an ID. In this case we have:
USERS_DATA = list(user_data_generator())
def test_id(user_data):
# Example of user_data: ("user1", "password1")
return user_data[0]
@pytest.fixture(
scope="session",
autouse=True,
params=USERS_DATA,
ids=test_id,
)
def test_user_fixture(request):
...
That means pytest
will pass each element in USERS_DATA
into the function test_id
和 use the return value as the ID.
Which method should we use? I believe the first method with TEST_IDS
are easier to underst和. The second method is more powerful 和 that is what I use in my projects.