2025-11-17
自动化测试框架
00
请注意,本文编写于 32 天前,最后修改于 32 天前,其中某些信息可能已经过时。

目录

前言
代码情景
解决方案

前言

  当前测试用例的断言与断言的后续操作是通过try...finally来进行管理的,但是当前的问题是,用例执行第一次失败的时候并没有走进finally操作(返回指定页面,数据的清理);只有在rerun失败的时候,才会进去finally操作,那么finally操作仅对后续的用例存在意义,而对当前用例的保障没有任何意义,那么问题出在哪里?

代码情景

python
try: for idx, time_key in enumerate(test_info['params']['time_keys'], start=1): with allure.step(f"⚙️正在进行系统时间{idx}设置与验证"): with allure.step(f"{idx}.1️⃣ 进行系统时间设置"): self.page.system_time_set(time_key) with allure.step(f"{idx}.2️⃣ 页面回退至识别页面"): self.page.page_back(3) with allure.step(f"{idx}.3️⃣ 进行添加用户的1:1验证"): self.page.one_to_one_id(user_id=user_id) self.page.one_to_one_pwd(pwd=pwd) self.page.page_back(2) time.sleep(0.5) with allure.step(f"{idx}.4️⃣ 获取报错提示信息进行断言"): msg = self.page.get_error_message(test_info["params"]["locator"]) assert msg == test_info["expected"]["assert"], ( f"期望提示:{test_info['expected']['assert']},实际提示:{msg}" ) time.sleep(3) with allure.step(f"{idx}.5️⃣ 返回Apps页面"): self.page.return_apps_page() finally: with allure.step("⚙️回退至用户管理页面"): if self.page.device(resourceId="com.testhnology.android.launcher:id/iv_home_menu"): self.page.return_apps_page() self.page.device(resourceId="com.testhnology.android.launcher:id/img").click()

原因分析

finish没有执行的原因是把finally放在了Allure step里面,断言在with allure.step()内部被抛出,导致pytest的finally不会立即触发,即allure捕获了异常,pytest的控制流没有真正的进入finally。

解决方案

要保证 finally 无论如何都执行,就必须把 try/finally 放在 Allure step 外层,修正后的代码如下:

python
try: with allure.step("⚙️进行系统日期的设置"): for year in [2025, 2026]: # ... 这里省略你的逻辑,照写即可 ... with allure.step(f"{idx}.4️⃣ 获取报错提示信息进行断言"): if year == 2026: msg = self.page.wait_for_error_message("verify_msg_loc") assert msg == test_info["expected"]["assert1"] else: msg = self.page.wait_for_error_message("verify_msg_failed") assert msg == test_info["expected"]["assert"] finally: with allure.step("⚠️ 清理:始终删除新增的用户"): with allure.step("⚙️回退至用户管理页面"): if self.page.device(resourceId="com.testhnology.android.launcher:id/iv_home_menu"): self.page.return_apps_page() self.page.device(resourceId="com.testhnology.android.launcher:id/img").click()

注意

  • pytest 控制流只认可 try/finally
  • allure.step 是 context manager,会中断 finally 的默认行为
  • try/finally 必须包裹 allure,而不是位于其内部
  • 断言写在try内即可

本文作者:精卫

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!