如何在Pytest同一浏览器会话内执行多测试并分别断言?
解决Pytest同浏览器会话多测试用例执行问题
问题背景
现有一套基于Pytest的测试框架,原driver fixture代码如下,默认每个测试函数都会生成新的Web Driver,测试完成后关闭浏览器:
@pytest.fixture def driver(some_request): # 获取所需驱动 driver = webdriver.Chrome() yield driver # 测试完成后关闭浏览器 driver.quit()
实际场景中需要在同一浏览器会话、同一页面连续执行多个测试(比如先测筛选功能,再测筛选器重置功能),最初的做法是把多个测试逻辑写在同一个测试函数里,但如果前面的断言失败,后续测试会直接终止,无法执行。
需要实现的流程:
- 用Web Driver打开页面
- 执行test1并断言
- 执行test2并断言(无论test1是否失败)
- 所有测试完成后关闭Driver
解决方案
第一步:调整Driver Fixture的作用域
首先修改fixture的scope参数,让Driver在整个模块或会话周期内只初始化一次,避免重复打开浏览器:
@pytest.fixture(scope="module") # 若需跨多个测试文件共享,可改为scope="session" def driver(some_request): # 初始化驱动并打开目标页面 driver = webdriver.Chrome() driver.get("https://your-target-page.com") yield driver # 所有测试完成后统一关闭浏览器 driver.quit()
第二步:选择测试执行方式
根据测试用例的组织需求,可选择以下两种方式之一:
方式一:使用Pytest子测试(Subtests)
将多个测试逻辑封装在同一个函数的子测试中,即使某个子测试断言失败,其他子测试依然会继续执行:
import pytest from selenium.webdriver.common.by import By def test_filter_and_reset(driver): # 子测试1:测试筛选功能 with pytest.subTest(msg="验证筛选功能"): driver.find_element(By.ID, "filter-input").send_keys("测试内容") driver.find_element(By.ID, "filter-btn").click() assert len(driver.find_elements(By.CLASS_NAME, "result-item")) > 0 # 子测试2:测试重置功能(不受前一个子测试结果影响) with pytest.subTest(msg="验证筛选器重置功能"): driver.find_element(By.ID, "reset-btn").click() assert driver.find_element(By.ID, "filter-input").get_attribute("value") == ""
方式二:拆分为独立测试函数并指定执行顺序
把测试拆分为独立的函数,利用scope="module"的fixture共享同一个Driver,再通过pytest-order插件指定执行顺序,确保测试按预期流程执行:
- 先安装插件:
pip install pytest-order
- 编写测试用例:
import pytest from selenium.webdriver.common.by import By @pytest.mark.order(1) def test_filter_function(driver): driver.find_element(By.ID, "filter-input").send_keys("测试内容") driver.find_element(By.ID, "filter-btn").click() assert len(driver.find_elements(By.CLASS_NAME, "result-item")) > 0 @pytest.mark.order(2) def test_filter_reset_function(driver): driver.find_element(By.ID, "reset-btn").click() assert driver.find_element(By.ID, "filter-input").get_attribute("value") == ""
这种方式下,即使test_filter_function断言失败,test_filter_reset_function依然会执行(除非使用了pytest -x参数终止执行)。
方案选择建议
- 若测试逻辑关联性极强,适合放在一起维护,优先选择子测试方式。
- 若追求测试用例的原子性、独立性,优先选择独立测试函数+执行顺序方式。
内容的提问来源于stack exchange,提问作者AlexStox
相关产品推荐
相关产品推荐

