异常自动截图
异常截图场景
- 场景
- 增加自动化测试代码的可测性
- 丰富报告
实现原理
- 装饰器
- 自动化关键数据记录
- 截图
- 日志
- page_source
实例
步骤
-
- 搭建装饰器框架
def ui_exception_record(func):
def inner(*args, **kwargs):
func(*args, **kwargs)
return inner
-
- 嵌入相关逻辑
-
- 需要通过 driver实例截图/打印page_source,装饰器需要先获取 driver实例对象
driver = args[0].drivertry:
# 当被装饰函数/方法发生异常,就捕获并做数据记录
return func(*args, **kwargs)
except Exception as e:
# 方案2
# driver = args[0].driver
# 出现异常的超级
print(f"出现异常:{e}")
# 截图操作
timestamp = int(time.time())
# 提前创建好 images 路径
image_path = f"./images/image_{timestamp}.PNG"
page_source_path = f"./page_source/page_source_{timestamp}.html"
# 截图
driver.save_screenshot(image_path)
# 将截图放入报告的数据中
allure.attach.file(image_path, name='picture', attachment_type=allure.attachment_type.PNG)
# 记录 page_source
with open(page_source_path, "w", encoding='utf-8') as file:
file.write(driver.page_source)
# 将截图数据放入报告的数据中
# allure.attachment_type.HTML 展示页面
# allure.attachment_type.TEXT 展示页面源码
allure.attach.file(page_source_path, name='pagesource', attachment_type=allure.attachment_type.HTML)
raise e
遇到的问题
-
目标1: 实现代码异常的时候,截图/打印page_source# 实现方法: try catch 配合截图/ page_source操作
-
问题一:异常处理会影响用例本身结果
- 解决方案:在exception之后再把异常抛出 raise Exception
-
问题二:异常捕获处理代码与业务代码无关,不能耦合
- 解决方案:使用装饰器装饰用例或者相关方法,就不会体现在源码中
-
问题三:被装饰还没有执行,还没有self.driver
- 解决方案1:获取driver放在函数执行之后
- 解决方案2:保证使用装饰器的时候,driver 已经声明
- 获取被装饰函数/方法的 self,也即是实例对象
- 通过 self 就可以拿到声明的实例变量
- 前提条件:被装饰的方法是一个实例方法# 实例需要有实例变量 self.driver
-
问题四:一旦被装饰方法有return返回值,会丢失返回值
- 解决方案:在装饰器中,当被装饰器装饰方法时,输入return func(*args, **kwargs)
-
代码实例
import time
import allure
from selenium import webdriver
from selenium.webdriver.common.by import By
# 搭建装饰器框架
# 嵌入相关逻辑
# 需要通过 driver实例截图/打印page_source,装饰器需要先获取 driver实例对象
def ui_exception_record(func):
def inner(*args, **kwargs):
driver = args[0].driver
try:
# 当被装饰函数/方法发生异常,就捕获并做数据记录
return func(*args, **kwargs)
except Exception as e:
# 方案2
# driver = args[0].driver
# 出现异常的超级
print(f"出现异常:{e}")
# 截图操作
timestamp = int(time.time())
# 提前创建好 images 路径
image_path = f"./images/image_{timestamp}.PNG"
page_source_path = f"./page_source/page_source_{timestamp}.html"
# 截图
driver.save_screenshot(image_path)
# 将截图放入报告的数据中
allure.attach.file(image_path, name='picture', attachment_type=allure.attachment_type.PNG)
# 记录 page_source
with open(page_source_path, "w", encoding='utf-8') as file:
file.write(driver.page_source)
# 将截图数据放入报告的数据中
# llure.attachment_type.HTML 展示页面
# llure.attachment_type.TEXT 展示页面源码
allure.attach.file(page_source_path, name='pagesource', attachment_type=allure.attachment_type.HTML)
raise e
return inner
class TestBaidu:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
def teardown_class(self):
self.driver.quit()
@ui_exception_record
def find(self):
return self.driver.find_element(By.ID, 'su1')
def test_baidu(self):
self.driver.get("https://www.baidu.com/")
self.find().click()