You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pytest同一浏览器会话内执行多测试并分别断言?

解决Pytest同浏览器会话多测试用例执行问题

问题背景

现有一套基于Pytest的测试框架,原driver fixture代码如下,默认每个测试函数都会生成新的Web Driver,测试完成后关闭浏览器:

@pytest.fixture
def driver(some_request):
    # 获取所需驱动
    driver = webdriver.Chrome()
    yield driver
    # 测试完成后关闭浏览器
    driver.quit()

实际场景中需要在同一浏览器会话、同一页面连续执行多个测试(比如先测筛选功能,再测筛选器重置功能),最初的做法是把多个测试逻辑写在同一个测试函数里,但如果前面的断言失败,后续测试会直接终止,无法执行。

需要实现的流程:

  1. 用Web Driver打开页面
  2. 执行test1并断言
  3. 执行test2并断言(无论test1是否失败)
  4. 所有测试完成后关闭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插件指定执行顺序,确保测试按预期流程执行:

  1. 先安装插件:
pip install pytest-order
  1. 编写测试用例:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:33:23