Selenium+pytest如何遍历嵌套列表录表单且不重复启停浏览器
问题原因
- 你当前使用
@pytest.mark.parametrize传参时,pytest会为每一组参数单独执行一次完整的测试函数 - 你的
setupfixture是function作用域,每次执行测试函数都会重新启动浏览器、执行结束后关闭浏览器,必然出现每组数据重启浏览器的问题 - 既然不能修改fixture作用域,核心解决思路是把多组数据的遍历逻辑放到单个测试函数内部完成,整个测试只触发一次fixture的初始化和销毁,全程复用同一个浏览器会话。
修复步骤
1. 修正Excel读取函数的逻辑bug
原代码用insert(i, tempDataList)插入数据时,因为行号起始值不是0,会导致返回的列表前面出现空元素,直接用append追加即可,同时补上工作簿关闭、空行过滤逻辑:
def fetchTestDataRowWise(worksheet_name, rowStartIndexDataStartReading, colFromWhereDataStartReading): dataFilePath = "..//..//TestData1.xlsx" workbook = openpyxl.load_workbook(dataFilePath, data_only=True) worksheet = workbook[worksheet_name] rows = worksheet.max_row cols = worksheet.max_column dataList = [] for i in range(rowStartIndexDataStartReading, rows + 1): tempDataList = [] for j in range(colFromWhereDataStartReading, cols + 1): cell_val = worksheet.cell(i, j).value if cell_val is not None: tempDataList.append(cell_val) # 过滤整行为空的无效数据 if tempDataList: dataList.append(tempDataList) workbook.close() return dataList
2. 调整测试用例结构
去掉parametrize装饰器,在测试函数内一次性拉取全量测试数据,循环执行单条SKU的录入+Add操作,全部数据处理完再触发Complete按钮:
class TestMaterialPerformCycleCount(BaseClass): @pytest.mark.usefixtures("setup") def test_PerformCycleCount(self): # 一次性读取所有测试数据,整个测试流程仅读取一次 all_sku_data = BaseClass.fetchTestDataRowWise("CycleCountTestData", 2, 1) # 登录操作仅需执行一次,放在循环外 userLogin = Login(self.driver) userLogin.login() cycle_count_page = MaterialPerformCycleCount(self.driver) # 遍历所有测试数据,逐组录入并点击Add SKU for data in all_sku_data: # 按你实际Excel列索引取值即可 cycle_count_page.enterItemNbr(data[1]) time.sleep(2) cycle_count_page.enterItemQty(int(data[2])) time.sleep(2) # 注意方法名要和你页面类封装的一致,原页面类方法是clickAddSKU,之前用例里的clickAddSKUbtn是笔误 cycle_count_page.clickAddSKU() # 所有SKU录入完成后,点击Complete按钮,替换成你自己封装的对应方法即可 cycle_count_page.click_complete_button()
补充说明
- 现有function级别的setup fixture不需要做任何修改,其他依赖该fixture的测试用例完全不受影响
- 硬编码的
time.sleep稳定性差,建议替换为Selenium显式等待,判断元素可交互后再执行操作 - 不要把登录、页面初始化这类只需要执行一次的操作放到循环内部,避免重复执行冗余步骤
内容的提问来源于stack exchange,提问作者Pardeep7
相关产品推荐
相关产品推荐

