Python 测开28期 - WL - 学习笔记 - 异常自动截图

异常自动截图

异常截图场景

  • 场景
    • 增加自动化测试代码的可测性
    • 丰富报告

实现原理

  • 装饰器
  • 自动化关键数据记录
    • 截图
    • 日志
    • page_source

实例

步骤
    1. 搭建装饰器框架
def ui_exception_record(func):
    def inner(*args, **kwargs):
        func(*args, **kwargs)
    return inner
    1. 嵌入相关逻辑
    1. 需要通过 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()