利用装饰器,帮你自动处理异常并优雅实现重跑case

简介: 利用装饰器,帮你自动处理异常并优雅实现重跑case

前言



同学们是否遇到过这些场景?


case因为网络波动而跑失败了?在最后时刻,系统弹出了一条骚扰短信遮挡了关键位置,脚本硬是没跑过去?又或者因为手机上的闹铃响起来,让脚本运行意外失败了?


相信很多同学都会想到用代码去处理这些异常,因为我们总不能时时刻刻盯着脚本运行,然后在出现异常时手动处理掉,但是代码可以帮我们实现自动处理异常。


但也有很多同学,因为处理异常复制粘贴了大量代码,用例脚本里面随处可见处理异常的代码。所以今天我们将教大家在不改动原有用例脚本的情况下,利用装饰器优雅地处理异常并实现case重试操作,同学们千万不能错过呀~


(PS:已会用装饰器的同学,可以直接拉到文末查看实操应用哦~)


1.装饰器的定义



装饰器可以在不改动原函数代码的情况下,添加其原本没有的功能。简单点说,就是修改其它函数的功能的函数。通过使用装饰器,我们可以让一个函数的功能变的更加强大,还可以让我们的代码更加简短整洁。


2.用简单的示例入门装饰器



首先我们定义了一个 test 函数,这个函数的作用就是打印出一句话:这是一个平平无奇的函数。


函数定义如下:


def test():
    print("这是一个平平无奇的函数")
test()
>>>输出:
# 这是一个平平无奇的函数
复制代码


如果需要print两次,大家会怎么实现呢?有同学说,直接复制一行print,也有同学说,直接在函数中增加一个for循环实现,其实都是可以的:


# 方式一
def test():
    print("这是一个平平无奇的函数")
    print("这是一个平平无奇的函数")
# 方式二
def test():
    for i in range(2):
        print("这是一个平平无奇的函数")
test()
>>>输出:
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
复制代码


假设我们要重复print两次,但又不想修改原函数的代码,我们要怎么做呢? 没错啦,我们可以定义装饰器来实现:


# 原函数
def test():
    print("这是一个平平无奇的函数")
# 定义1个装饰器
def loop(func):
    def wrapper(*args, **kw):
        for i in range(2):
            func(*args, **kw)
    return wrapper
复制代码


可以看到,我们并没有改变原有函数,但是我们用装饰器改变了原函数的功能,用上述装饰器帮助我们重复运行2次原函数。


那么接下来,我们继续来看看如何使用装饰器:


方式一:不使用语法糖@符号的调用方法:


loop(test)()
>>>输出:
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
复制代码


方式二:使用语法糖@符号的调用方法:


@loop
def test():
    print("这是一个平平无奇的函数")
test()
>>>输出:
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
复制代码


实际上装饰器可以多次叠加,比如:


@loop
@loop
def test():
    print("这是一个平平无奇的函数")
test()
>>>输出:
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
复制代码


有一点值得注意的地方,同学们猜一猜,如果我们叠加三次装饰器,会出现什么结果呢?(看到这里的同学可以先思考一下,然后再动手跑一下看看是不是你预想的结果)


@loop
@loop
@loop
def test():
    print("这是一个平平无奇的函数")
test()
>>>输出:
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
# 这是一个平平无奇的函数
复制代码


可以看到,输出结果并不是6次,而是8次,为什么呢?我们用普通的调用方式来分析一下就知道了:


上述代码就相当于:loop(loop(loop(test)))(),真正调用的是最外面那层。 当你调用多次时,装饰器将函数连同装饰器自身作为参数一起循环执行了,所以实际执行次数为2×(2×2),即8次。


如果你需要定义具体的执行次数,可以直接在装饰器中传入参数实现,具体如下:


def loop(times):
    def decorator(func):
        def wrapper(*args, **kw):
            for i in range(times):
                func(i, **kw)
        return wrapper
    return decorator
@loop(6)
def test(num):
    print(f"这是一个平平无奇的函数, 第{num+1}次运行")
test()
输出:
# 这是一个平平无奇的函数, 第1次运行
# 这是一个平平无奇的函数, 第2次运行
# 这是一个平平无奇的函数, 第3次运行
# 这是一个平平无奇的函数, 第4次运行
# 这是一个平平无奇的函数, 第5次运行
# 这是一个平平无奇的函数, 第6次运行
复制代码


3.应用装饰器实现Airtest脚本失败自动重跑



举个例子,你正在跑一个自动化测试脚本,突然间设备的闹钟响了,而刚好闹钟的界面遮挡住了你要操作的那个按钮,最终导致脚本运行失败了。没办法,你只能关掉闹钟再重新运行一次脚本。


在这个测试场景中,我们如何应用装饰器帮助我们解决闹钟异常,然后重跑我们的测试用例呢?答案如下:


网络异常,图片无法展示
|


我们新建了1个装饰器,这个装饰器会尝试运行我们的用例,如果遇到闹钟遮挡,则会自动处理掉这个闹钟,然后再重跑用例,最终还会打印出重跑结果,效果如下:


网络异常,图片无法展示
|


可以看到,我们在没有改变用例函数的情况下,增加了装饰器,使得原函数有了处理异常和重跑的功能,这就是装饰器函数的魅力所在。


最后借用某位不知名大佬说的话:别妄想着看看就能理解,动手跑一跑代码,一切都豁然开朗了。

相关文章
|
JavaScript 前端开发
vue element plus Empty 空状态
vue element plus Empty 空状态
351 0
vue element plus Empty 空状态
|
消息中间件 Java 关系型数据库
10道不得不会的Docker面试题
10道不得不会的Docker面试题,10道不得不会的Docker面试题
9494 1
10道不得不会的Docker面试题
|
缓存 NoSQL Go
通过 SingleFlight 模式学习 Go 并发编程
通过 SingleFlight 模式学习 Go 并发编程
ly~
|
12月前
|
数据可视化 BI API
除了 OpenGL,还有哪些常用的图形库可以在 C 语言中使用?
除了OpenGL,C语言中还有多个常用的图形库:SDL,适合初学者,用于2D游戏和多媒体应用;Allegro,高性能,支持2D/3D图形,广泛应用于游戏开发;Cairo,矢量图形库,支持高质量图形输出,适用于数据可视化;SFML,提供简单接口,用于2D/3D游戏及多媒体应用;GTK+,开源窗口工具包,用于创建图形用户界面。这些库各有特色,适用于不同的开发需求。
ly~
2590 4
|
NoSQL Dubbo 应用服务中间件
Dubbo Zookeeper(一)Zookeeper初识
Dubbo Zookeeper(一)Zookeeper初识
|
SQL 安全 API
互联网并发与安全系列教程(09) -基于AccessToken方式实现API设计
互联网并发与安全系列教程(09) -基于AccessToken方式实现API设计
200 0
|
监控 关系型数据库 数据库
关系型数据库关系维护
【5月更文挑战第17天】
225 4
|
监控 安全 网络安全
探讨网站加密访问的安全性问题:HTTPS的防护与挑战
**探讨HTTPS在网站加密中的角色,提供数据加密和身份验证,防范中间人攻击。心脏滴血漏洞示例显示持续维护的必要性。面临证书管理、性能影响和高级攻击挑战,应对措施包括更新、HSTS策略及用户教育。HTTPS是安全基础,但需不断优化以应对新威胁。**
788 2
|
SQL JSON 关系型数据库
PostgreSQL安装、配置及简单使用方法
一、PostgreSQL简介 1、什么是PostgreSQL PostgreSQL数据库是目前功能最强大的开源数据库,支持丰富的数据类型(如JSON何JSONB类型,数组类型)和自定义类型。而且它提供了丰富的接口,可以很容易地扩展它的功能,如可以在GiST框架下实现自己的索引类型等,它还支持使用C语言写自定义函数、触发器,也支持使用流行的语言写自定义函数,比如其中的PL/Perl提供了使用Perl语言写自定义函数的功能,当然还有PL/Python、PL/Tcl,等等。 2、PostgreSQL数据库的优势 PostgreSQL数据库是目前功能最强大的开源数据库,它是最接近工业标准SQL
2044 0
|
缓存 算法 搜索推荐
阿里资深架构师三年整理分享:java面试核心知识点原理篇文档
前言 本文是对Java程序员面试必备知识点的总结,详细讲解了JVM原理、多线程、数据结构和算法、分布式缓存、设计模式等内容,希望读者能通过阅读本书对Java的基础原理有更深入、全面的理解。 面试官通常会在短短两小时内对面试者的知识结构进行全面了解,面试者在回答问题时如果拖泥带水且不能直击问题的本质,则很难充分表现自己,最终影响面试结果。针对这种情况,本文在讲解知识点时不拖泥带水,力求精简,详细介绍了Java程序员面试时常被问及的核心知识点。
346 0