pytest Selenium如何对整套测试套件参数化而非单测试用例参数化
问题原因
你遇到的执行顺序问题本质是两个因素导致的:
- pytest默认执行逻辑是按测试用例/模块分组,会先跑完同一测试节点的所有参数化实例,再执行下一个测试节点
- 你把有强顺序依赖的完整业务流程拆成了多个独立测试文件,pytest默认不会保证多文件的执行顺序
推荐解决方案(改动最小,符合测试逻辑)
由于你的登录→填信息→提交→登出是强依赖的完整流程,建议将所有步骤整合到同一个测试类中,pytest会默认按类内方法的定义顺序执行,搭配参数化fixture,天然就能实现「每个员工跑完所有流程再换下一个」的需求。
代码修改示例
1. conftest.py 修改
import pytest from selenium import webdriver my_test_data = { "employee_1": { "personal_information": {"first_name":"张三", "last_name":"张"}, "education_information": {"highest_degree":"本科", "university_name":"XX大学"}, "work_experience_information": {"work_experience":"5年", "current_organization_name":"XX公司"}, }, "employee_2": { "personal_information": {"first_name":"李四", "last_name":"李"}, "education_information": {"highest_degree":"硕士", "university_name":"YY大学"}, "work_experience_information": {"work_experience":"3年", "current_organization_name":"YY公司"}, } # 后续追加更多员工 } # 全局存储所有员工的session_id,session级fixture全程唯一 @pytest.fixture(scope="session") def all_session_ids(): return [] @pytest.fixture(scope="class", params=my_test_data.keys()) def test_setup(request, all_session_ids): driver = webdriver.Chrome() driver.get("你的系统地址") # 传入当前员工数据、driver、全局session_id列表 yield driver, my_test_data[request.param], all_session_ids driver.quit() # 所有测试跑完后触发,发送汇总邮件 @pytest.fixture(scope="session", autouse=True) def send_summary_email(all_session_ids): yield # 这里写你的发送邮件逻辑,直接取all_session_ids里的所有ID即可 print("所有测试完成,session_id列表:", all_session_ids)
2. 测试流程代码(合并为单个文件test_employee_flow.py即可)
import pytest import unittest # 你的页面对象类导入 # from xxx import PersonalInformationPage, EducationInformationPage, WorkExperienceInformationPage @pytest.mark.usefixtures("test_setup") class TestEmployeeFullFlow(unittest.TestCase): @pytest.fixture(autouse=True) def class_setup(self, test_setup): self.driver = test_setup[0] self.test_data = test_setup[1] self.all_session_ids = test_setup[2] # 初始化所有页面对象 # self.personal_page = PersonalInformationPage(driver=self.driver) # self.education_page = EducationInformationPage(driver=self.driver) # self.work_page = WorkExperienceInformationPage(driver=self.driver) def test_1_login(self): # 你的登录逻辑 pass def test_2_fill_personal_info(self): # 填写个人信息逻辑 # self.personal_page.send_first_name(self.test_data["personal_information"]["first_name"]) # self.personal_page.send_last_name(self.test_data["personal_information"]["last_name"]) # self.personal_page.click_on_next_button() pass def test_3_fill_education_info(self): # 填写教育信息逻辑 # self.education_page.send_highest_degree(self.test_data["education_information"]["highest_degree"]) # self.education_page.send_university_name(self.test_data["education_information"]["university_name"]) # self.education_page.click_on_next_button() pass def test_4_fill_work_experience(self): # 填写工作经验逻辑 # self.work_page.send_work_experience(self.test_data["work_experience_information"]["work_experience"]) # self.work_page.send_current_organization_name(self.test_data["work_experience_information"]["current_organization_name"]) # self.work_page.submit() pass def test_5_capture_session_id(self): # 抓取当前员工的session_id,追加到全局列表 session_id = self.driver.find_element("id", "你的session_id元素ID").text self.all_session_ids.append(session_id) def test_6_logout(self): # 登出逻辑 pass
执行pytest -v -s后,就会按你期望的顺序执行:员工1跑完全部6个测试方法→员工2跑完全部6个测试方法,所有执行完成后自动触发发邮件的逻辑。
保留多文件结构的解决方案(不推荐,依赖插件)
如果你一定要保留原来的多测试文件结构,需要做如下修改:
- 安装
pytest-order插件:pip install pytest-order - 在每个测试文件的测试类上加顺序标记,比如登录类加
@pytest.mark.order(1),个人信息类加@pytest.mark.order(2),以此类推 - 在项目根目录新建
pytest.ini,添加配置:
[pytest] order_parameters = all
配置完成后执行命令就会按参数分组执行,同一个员工的所有测试文件跑完再换下一个。
内容的提问来源于stack exchange,提问作者Mari Kannan B
相关产品推荐
相关产品推荐

