[英]Pytest - how to order test execution in parametrized tests by parameter first
I have the following parametrized test:我有以下参数化测试:
import pytest
@pytest.mark.parametrize("url1", ["url0001", "url0002", "url0003"], indirect=False)
class Test01:
def test01(self, url1):
print(url1)
assert url1 == f"{url1}"
def test02(self, url1):
print(url1)
assert url1 == f"{url1}"
Result:结果:
venv/test_url_fixt.py::Test01::test01[url0001] PASSED [ 16%]url0001
venv/test_url_fixt.py::Test01::test01[url0002] PASSED [ 33%]url0002
venv/test_url_fixt.py::Test01::test01[url0003] PASSED [ 50%]url0003
venv/test_url_fixt.py::Test01::test02[url0001] PASSED [ 66%]url0001
venv/test_url_fixt.py::Test01::test02[url0002] PASSED [ 83%]url0002
venv/test_url_fixt.py::Test01::test02[url0003] PASSED [100%]url0003
============================== 6 passed in 0.03s ==============================
Process finished with exit code 0
Target result:目标结果:
venv/test_url_fixt.py::Test01::test01[url0001] PASSED [ 16%]url0001
venv/test_url_fixt.py::Test01::test02[url0001] PASSED [ 33%]url0001
venv/test_url_fixt.py::Test01::test01[url0002] PASSED [ 50%]url0002
venv/test_url_fixt.py::Test01::test02[url0002] PASSED [ 66%]url0002
venv/test_url_fixt.py::Test01::test01[url0003] PASSED [ 83%]url0003
venv/test_url_fixt.py::Test01::test02[url0003] PASSED [100%]url0003
============================== 6 passed in 0.03s ==============================
Process finished with exit code 0
Info:信息:
I just need to execute test01
with url1
= "url0001" and test02
with url1
= "url0001" first, then loop over all tests with the next parameter, eg test01
with url1
= "url0002", test02
with url1
= "url0002" and so on.我只需
url1
test01
"url0001" 的test02
和带有url1
= "url0001" 的 test02,然后使用下一个参数循环所有测试,例如带有test01
= "url0002" 的test02
,带有url1
= "url0002" 的url1
等等上。 I have the list of urls and want to execute properly set of tests with that list of urls.我有 url 列表,并希望使用该 url 列表执行正确的测试集。
update更新
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from allure_commons.types import AttachmentType
import pytest
from selenium.common.exceptions import NoSuchElementException
import time
import logging
import allure
driver = webdriver.Chrome(executable_path=r'C:\webdrivers\chromedriver.exe')
# Logger
logging.basicConfig(filename="C:/LPsLogs/test.log",
format='%(asctime)s: %(levelname)s: %(message)s',
datefmt='%m/%d/%Y %H:%M:%S')
logger = logging.getLogger()
logger.setLevel(logging.INFO)
wait = WebDriverWait(driver, 10)
driver.implicitly_wait(5)
ec = EC
goxp = driver.find_element_by_xpath
goid = driver.find_element_by_id
keys = Keys
original_window = driver.current_window_handle
# Urls
sslurl = "https://www.sslshopper.com/ssl-checker.html"
# Locators
# xpath
sslpch = "//h1"
u1chb1 = "//div[@id='checkData']/descendant::td[1]"
u1chb2 = "//div[@id='checkData']/descendant::td[3]"
u1chb3 = "//div[@id='checkData']/descendant::td[5]"
u1chb4 = "//div[@id='checkData']/descendant::td[7]"
u1chb5 = "//div[@id='checkData']/descendant::td[11]"
u1chb6 = "//div[@id='checkData']/descendant::td[15]"
# id
hostname = "hostname"
expdate = "cert_expiration_days"
@allure.severity(allure.severity_level.BLOCKER)
def test_go_sslcheck():
logger.info("Testing started")
driver.maximize_window()
driver.get(sslurl)
wait.until(EC.visibility_of_element_located((By.XPATH, sslpch)))
sslchecker = driver.find_element_by_xpath(sslpch).text
if sslchecker == 'SSL Checker':
assert True
else:
logging.error('Error - def test_go_sslcheck module', exc_info=True)
allure.attach(driver.get_screenshot_as_png(), name="testLoginScreen", attachment_type=AttachmentType.PNG)
assert False
@pytest.mark.parametrize("url", ["google.com",
"https://expired.badssl.com"
])
class TestSSL:
@allure.severity(allure.severity_level.CRITICAL)
def test_url_input(self, url):
try:
input_hostname = goid(hostname)
input_hostname.send_keys(url)
input_hostname.send_keys(keys.ENTER)
time.sleep(2)
print(f"{url} has been entered")
assert True
input_hostname.clear()
except (Exception, NameError, AssertionError):
allure.attach(driver.get_screenshot_as_png(), name="testLoginScreen", attachment_type=AttachmentType.PNG)
logging.error('Error - url_input module', exc_info=True)
assert False
@allure.severity(allure.severity_level.CRITICAL)
def test_url_checkbox1(self, url):
wait.until(EC.visibility_of_element_located((By.XPATH, u1chb1)))
u1chb1ch = driver.find_element_by_xpath(u1chb1).get_attribute('class')
if u1chb1ch == 'passed':
print(f"{url} - test_url_checkbox1 - PASS")
assert True
else:
allure.attach(driver.get_screenshot_as_png(), name="testLoginScreen", attachment_type=AttachmentType.PNG)
logging.error(f'{url} - checkbox 1 - FAILED', exc_info=True)
assert False
@allure.severity(allure.severity_level.CRITICAL)
def test_url_checkbox2(self, url):
wait.until(EC.visibility_of_element_located((By.XPATH, u1chb2)))
u1chb2ch = driver.find_element_by_xpath(u1chb2).get_attribute('class')
if u1chb2ch == 'passed':
print(f"{url} - test_url_checkbox2 - PASS")
assert True
else:
allure.attach(driver.get_screenshot_as_png(), name="testLoginScreen", attachment_type=AttachmentType.PNG)
logging.error(f'{url} - checkbox 2 - FAILED', exc_info=True)
assert False
@allure.severity(allure.severity_level.CRITICAL)
def test_url_checkbox3(self, url):
wait.until(EC.visibility_of_element_located((By.XPATH, u1chb3)))
u1chb3ch = driver.find_element_by_xpath(u1chb3).get_attribute('class')
if u1chb3ch == 'passed':
print(f"{url} - test_url_checkbox3 - PASS")
assert True
else:
allure.attach(driver.get_screenshot_as_png(), name="testLoginScreen", attachment_type=AttachmentType.PNG)
logging.error(f'{url} - checkbox 3 - FAILED', exc_info=True)
assert False
@allure.severity(allure.severity_level.CRITICAL)
def test_url_checkbox4(self, url):
wait.until(EC.visibility_of_element_located((By.XPATH, u1chb4)))
u1chb4ch = driver.find_element_by_xpath(u1chb4).get_attribute('class')
if u1chb4ch == 'passed':
print(f"{url} - test_url_checkbox4 - PASS")
assert True
else:
allure.attach(driver.get_screenshot_as_png(), name="testLoginScreen", attachment_type=AttachmentType.PNG)
logging.error(f'{url} - checkbox 4 - FAILED', exc_info=True)
assert False
@allure.severity(allure.severity_level.CRITICAL)
def test_url_checkbox5(self, url):
wait.until(EC.visibility_of_element_located((By.XPATH, u1chb5)))
u1chb5ch = driver.find_element_by_xpath(u1chb5).get_attribute('class')
if u1chb5ch == 'passed':
print(f"{url} - test_url_checkbox5 - PASS")
assert True
else:
allure.attach(driver.get_screenshot_as_png(), name="testLoginScreen", attachment_type=AttachmentType.PNG)
logging.error(f'{url} - checkbox 5 - FAILED', exc_info=True)
assert False
@allure.severity(allure.severity_level.CRITICAL)
def test_url_checkbox6(self, url):
wait.until(EC.visibility_of_element_located((By.XPATH, u1chb6)))
u1chb6ch = driver.find_element_by_xpath(u1chb6).get_attribute('class')
if u1chb6ch == 'passed':
print(f"{url} - test_url_checkbox6 - PASS")
assert True
else:
allure.attach(driver.get_screenshot_as_png(), name="testLoginScreen", attachment_type=AttachmentType.PNG)
logging.error(f'{url} - checkbox 6 - FAILED', exc_info=True)
assert False
@allure.severity(allure.severity_level.NORMAL)
def test_url_expdate_w(self, url):
expdatech = driver.find_element_by_id(expdate).text
if int(expdatech) > 7:
print(f"{url} - expdate more than 7 days - PASS")
assert True
else:
allure.attach(driver.get_screenshot_as_png(), name="testLoginScreen", attachment_type=AttachmentType.PNG)
print(expdatech)
logging.warning(f"{url} SSL certificate will expire in less than 7 days, days left: {expdatech}", exc_info=True)
assert False
def test_close_browser():
try:
logger.info("Testing finished")
driver.close()
assert True
except (Exception, NameError, AssertionError):
logging.error('Error - close_browser module', exc_info=True)
assert False
Result of first test: empty suite with conftest in comments and I have not knowledge hot to run it separately (tried to learn, but too hard for me for now).第一次测试的结果:评论中有conftest的空套件,我不知道单独运行它(试图学习,但现在对我来说太难了)。
You can change the order of the items in the pytest_collection_modifyitems
hook.您可以更改
pytest_collection_modifyitems
挂钩中项目的顺序。 If you put this in your conftest.py
:如果你把它放在你的
conftest.py
中:
def pytest_collection_modifyitems(config, items):
def param_part(item):
# check for the wanted module and test class
if item.nodeid.startswith("test_urls.py::TestSSL::"):
# find the start of the parameter part in the nodeid
index = item.nodeid.find('[')
if index > 0:
# sort by parameter name
return item.name[item.nodeid.index('['):]
# for all other cases, sort by node id as usual
return item.nodeid
# re-order the items using the param_part function as key
items[:] = sorted(items, key=param_part)
Here is the output of pytest -vv
for your example:以下是
pytest -vv
的 output 示例:
================================================= test session starts =================================================
...
collected 6 items
test_paramtrize_order.py::Test01::test01[url0001] PASSED [ 16%]
test_paramtrize_order.py::Test01::test02[url0001] PASSED [ 33%]
test_paramtrize_order.py::Test01::test01[url0002] PASSED [ 50%]
test_paramtrize_order.py::Test01::test02[url0002] PASSED [ 66%]
test_paramtrize_order.py::Test01::test01[url0003] PASSED [ 83%]
test_paramtrize_order.py::Test01::test02[url0003] PASSED [100%]
================================================== 6 passed in 0.09s ==================================================
This will change the order only for the parametrized tests in the module test_urls.py
and the class TestSSL
.这将仅更改模块
test_urls.py
和 class TestSSL
中参数化测试的顺序。 If you want to have this for more or all parametrized tests, you can adapt or remove the check in param_part
.如果您想在更多或所有参数化测试中使用它,您可以调整或删除
param_part
中的检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.