自动化测试-如何优雅实现方法的依赖

在复杂的测试场景中,常常会存在用例依赖,以一个接口自动化平台为例,依赖关系:

创建用例 --> 创建模块 --> 创建项目 --> 登录。

用例依赖的问题

• 用例的依赖对于的执行顺序有严格的要求,比如让被依赖的方法先执行。

• 一旦使用用例依赖,依赖的用例就无法单独执行了,按照用例的设计原则,每条用例都应该独立执行。

正确的做法

我们应该将依赖的操作封装成方法调用。如果能通过装饰器实现调用,那就很有趣了。

aomaker[1] 提供了这种装饰器的实现,seldom 进行了复刻,只是用法上有所不同。

类内部方法调用

我们可以在测试类下面,创建普通的方法。然后通过@dependent_func()装饰器调用他。

import seldom
from seldom.testdata import get_md5
from seldom.utils import cache, dependent_funcclass DependentTest(seldom.TestCase):@staticmethoddef user_login(username, password):"""模拟用户登录,获取登录token"""return get_md5(username+password)@dependent_func(user_login, username="tom", password="t123")def test_case(self,):"""sample test case"""token = cache.get("user_login")print("token", token)if __name__ == '__main__':seldom.main(debug=True)cache.clear()

说明

这个例子涉及到不少知识点。

1.test_case() 用例依赖 user_login() 方法,通过 @dependent_func() 装饰器调用 user_login 方法。

2.user_login() 方法运行的时候需要参数(username、password),可以直接在 @dependent_func() 装饰器中设置参数:username=“tom”、 password=“t123”。

3.user_login() 方法运行运行完会生成 token, 保存于 cache中,通过 cache.get() 可以获取到token, 默认通过方法名user_login 作为key获取。

4.为了简化代码,生成token 是通过 get_md5() 根据传入的参数生成的一个 md5 值。

5.cache.clear() 用于清空缓存, 再次调用 user_login() 方法直接不执行,应为cache已经有上次的执行结果了。

执行日志

python zzz_demo.py
...
test_case (zzz_demo.DependentTest.test_case)
sample test case ... 2023-11-15 23:26:36 | INFO     | dependence.py | 🔗 <test_case> depends on <user_login>, execute.
2023-11-15 23:26:36 | INFO     | cache.py | 💾 Set cache data: user_login = 35e0ff9c4cba89998dda8255d0eb5408
2023-11-15 23:26:36 | INFO     | cache.py | 💾 Get cache data: user_login = 35e0ff9c4cba89998dda8255d0eb5408
token 35e0ff9c4cba89998dda8255d0eb5408
ok----------------------------------------------------------------------
Ran 1 test in 0.005sOK
2023-11-15 23:26:36 | SUCCESS  | runner.py | A run the test in debug mode without generating HTML report!
2023-11-15 23:26:36 | INFO     | cache.py | 💾 Clear all cache data

外部类方法依赖

•创建依赖方法

# common.py
from seldom.testdata import get_md5class Login:@staticmethoddef account_login(username, password):"""模拟用户&密码登录,获取登录token"""return get_md5(username+password)login=Login()

•用例引用依赖方法

import seldom
from seldom.utils import cache, dependent_func
from common import Login # 方式1:引用依赖类
# from common import login  # 方式2:引用初始化好的类对象class DependentTest(seldom.TestCase):@dependent_func(Login().account_login, key_name="token1", username="tom", password="t123")# @dependent_func(login.account_login, key_name="token1", username="tom", password="t123")def test_case(self):"""Used tuple test data"""token = cache.get("token1")print("token", token)if __name__ == '__main__':seldom.main(debug=True)

说明

1.Common 类的account_login()方法可以不设置为静态方法,导入时需要类需要加括号:Common().user_login。 或者先初始化类对象login=Login() 再调用。

2.key_name 指定缓存的 key,如果指定为token1, 从缓存读取也使用这个cache.get(“token1”)。

多重方法依赖

复杂的场景当然是需要多重依赖的。

1.被依赖的方法可以进一步使用 dependent_func()装饰器进行多重复依赖。

查询模块 --> 查询项目 --> 登录

# common.py
from seldom.testdata import get_md5, get_int
from seldom.utils import cache, dependent_funcclass Login:@staticmethoddef account_login(username, password):"""模拟用户&密码登录,获取登录token"""return get_md5(username+password)class DepFunc:@staticmethod@dependent_func(Login.account_login, key_name="token", username="jack", password="456")def get_project_id():token = cache.get("token")print(f"使用token:{token} 查询项目, 返回项目ID")return get_int(1, 1000)@staticmethod@dependent_func(get_project_id, key_name="pid")def get_module_id():pid = cache.get("pid")print(f"使用项目ID:{pid} 查询模块, 返回模块ID")return get_int(1, 1000)

在用例中直接调用 DepFunc.get_module_id 方法即可。

import seldom
from seldom.utils import cache, dependent_func
from common import DepFuncclass DependentTest(seldom.TestCase):@dependent_func(DepFunc.get_module_id, key_name="mid")def test_case(self):"""sample test case"""mid = cache.get("mid")print(f"模块ID: {mid}")if __name__ == '__main__':seldom.main(debug=True)cache.clear()

2.测试用例也可以同时使用多个 @dependent_func() 装饰器依赖多个方法,顺序由上到下执行,这种方式主要用于被依赖的方法之间没有依赖关系。

# common.py
from seldom.testdata import get_int, usernameclass DataFunc:@staticmethoddef get_name():return username(language="zh")@staticmethoddef get_age():return get_int(1, 99)

在用例中使用多个@dependent_func()依赖装饰器。

import seldom
from seldom.utils import cache, dependent_func
from common import DataFuncclass DependentTest(seldom.TestCase):@dependent_func(DataFunc.get_name, key_name="name")@dependent_func(DataFunc.get_age, key_name="age")def test_case(self):"""sample test case"""name = cache.get("name")age = cache.get("age")print(f"名字: {name}, 年龄: {age}")if __name__ == '__main__':seldom.main(debug=True)cache.clear()

参数化使用

参数化 @data()、 @file_data() 是seldom最重要的功能之一,能否和 @dependent_func() 一起使用? 当然可以。

import seldom
from seldom import data
from seldom.testdata import get_md5
from seldom.utils import cache, dependent_funcclass DependentTest(seldom.TestCase):@staticmethoddef user_login(username, password):"""模拟用户登录,获取登录token"""return get_md5(username+password)@data([("case1", "foo"),("case2", "bar"),])@dependent_func(user_login, username="tom", password="t123")def test_case(self, _, keyword):"""Used tuple test data"""token = cache.get("user_login")print(keyword, "token", token)if __name__ == '__main__':seldom.main(debug=True)cache.clear()

说明

1.@data() 装饰器必须写在 @dependent_func() 的上面。

2.运行两条用例,user_login() 被执行过一次后,第二次则不需要重复执行,直接返回结果。

 

总结:

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/820603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

市面上加密混淆软件的比较和推荐

引言 市面上有许多加密混淆软件可供开发者使用&#xff0c;但哪些软件是最好用的&#xff1f;哪些软件受到开发者的喜爱&#xff1f;本文将根据一次在CSDN上的投票结果&#xff0c;为大家介绍几款在程序员中普及度较高的加密软件。以下是投票结果&#xff0c;希望能对大家的选择…

JSON数据格式讲解与cJSON库的使用

文章目录 写在前面一、安装cJSON二、使用cJSON1、使用的文件2、如何传输数据&#xff1a;**** 三、JSON语法四、cJSON函数讲解1、cJSON结构体 **2、cJSON结构体与字符串之间的转换&#xff08;重要&#xff09;2.1、标题将cJSON结构体转换为字符串(常用)2.2、将字符串转为cJSON…

看看《MATLAB科研绘图与学术图表绘制从入门到精通》示例:绘制山鸢尾萼片长度和萼片宽度的小提琴图

使用MATLAB绘制鸢尾花数据集&#xff08; fisheriris&#xff09;中山鸢尾&#xff08; Iris Setosa&#xff09;的萼片长度和 萼片宽度的小提琴图。这将帮助我们更好地了解山鸢尾的这两个特征的数据分布情况&#xff0c;包括它们的 中位数、四分位范围及密度估计。这种可视化工…

华为配置路由式Proxy ARP示例

配置路由式Proxy ARP示例 组网图形 图1 配置路由式Proxy ARP组网图 路由式Proxy ARP简介配置注意事项组网需求配置思路操作步骤配置文件 路由式Proxy ARP简介 企业内部进行子网划分时&#xff0c;可能会出现两个子网网络属于同一网段&#xff0c;但是却不属于同一物理网络的情…

C++ 类模板分文件编写

类模板分文件编写&#xff1a; 类模板成员函数 分文件编写 产生的问题以及解决方式是什么呢&#xff1f; 问题描述 类模板中**成员函数**创建时机是在**调用**阶段&#xff0c;导致分文件编写时**链接**不到 解决方案&#xff1a; 1、直接包含.cpp源文件&#xff1a; person…

【重磅更新】开源表单系统填鸭表单v5版发布!

亲爱的TDucker&#xff0c;你们好。 真诚感谢您对填鸭表单的关注与支持。今天我们将为您带来新版本的更新说明&#xff0c;以便您更好的使用我们的产品。 社区版版V5更新概览&#xff1a; ✅ 增加WebHook数据推送功能&#xff0c;集成TReport实现数据大屏展示。 ✅ 增加主题…

LeetCode-Java:303、304区域检索(前缀和)

文章目录 题目303、区域和检索&#xff08;数组不可变&#xff09;304、二维区域和检索&#xff08;矩阵不可变&#xff09; 解①303&#xff0c;一维前缀和②304&#xff0c;二维前缀和 算法前缀和一维前缀和二维前缀和 题目 303、区域和检索&#xff08;数组不可变&#xff…

DateTimeFormat 和 JsonFormat 应用场景详解

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【javaWeb 第七篇】后端-Spring

Spring SpringspringBoot请求简单参数实体参数数组集合参数日期参数JSON参数路径参数 响应数据分层解耦三层架构解耦操作Bean的声明Bean组件扫描问题DI详解 Spring 详细介绍结合官网查看&#xff1a;https://spring.io/why-spring Spring发展到今天已经形成一种开发生态圈&…

覆盖最全面的学术论文写作的70类细节150+ChatGPT提示词

点击下方▼▼▼▼链接直达AIPaperPass &#xff01; AIPaperPass - AI论文写作指导平台 这篇文章小编介绍了专门为论文写作定制的ChatGPT提示词&#xff0c;旨在激发创造力并为你的论文提供独特的想法和见解。通过简单的短语或指令&#xff0c;你可以解锁ChatGPT AI模型的潜力…

激光车型识别仪:交通管理领域的技术革新与应用探索

激光车型识别仪&#xff1a;交通管理领域的技术革新与应用探索 在交通管理领域&#xff0c;随着技术的不断进步&#xff0c;各种智能化设备逐渐崭露头角。其中&#xff0c;激光车型识别仪作为一种基于激光技术的车辆识别设备&#xff0c;正以其高精度、强抗干扰能力等特点&…

JIT在汽车行业中的革命性应用:颠覆传统制造模式,引领智能制造新时代

随着科技的飞速发展和市场竞争的日益激烈&#xff0c;汽车行业正面临着前所未有的变革。其中&#xff0c;准时制生产&#xff08;Just-In-Time&#xff0c;简称JIT&#xff09;作为一种先进的生产管理方式&#xff0c;已经在汽车行业中得到了广泛应用&#xff0c;成为推动汽车产…

word文件的创建时间和修改时间可以更改吗?答案是肯定的 文件属性修改的方法

一&#xff0c;引言 在日常生活和工作中&#xff0c;我们经常需要处理各种Word文件。有时&#xff0c;由于某些原因&#xff0c;我们可能需要更改Word文件的创建时间和修改时间。虽然这听起来可能有些复杂&#xff0c;但实际上&#xff0c;通过一些简单的方法和工具&#xff0…

社区养老服务系统|基于springboot社区养老服务系统设计与实现(源码+数据库+文档)

社区养老服务系统目录 目录 基于springboot社区养老服务系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员部分功能 &#xff08;1&#xff09; 用户管理 &#xff08;2&#xff09;服务种类管理 &#xff08;3&#xff09;社区服务管理 &#xff08…

【数据分析面试】21.Spotify 音乐数据库搭建(SQL主键和外键)

题目&#xff1a;音乐数据库设计 假设现在你在Spotify工作&#xff0c;你需要设计一个用于存储歌曲元数据的关系型数据库。 数据库要求包括歌曲标题、歌曲长度、歌曲添加到平台的日期、艺术家、专辑、曲目号&#xff08;在专辑中的顺序&#xff09;、歌曲的发行年份以及流派等…

FebHost:为什么注册.BE比利时域名?

.be 是比利时的国家代码顶级域名&#xff08;ccTLD&#xff09;&#xff0c;通常用于与该国有关的网网站。这个域名为那些希望在线上建立与比利时有关联系的个人、公司和组织提供了一个重要的网络标识。 .be 域名于1988年创建&#xff0c;由.BE域名注册机构管理&#xff0c;这…

【k8s】:深入理解 Kubernetes 中的污点(Taints)与容忍度(Tolerations)

【k8s】&#xff1a;深入理解 Kubernetes 中的污点&#xff08;Taints&#xff09;与容忍度&#xff08;Tolerations&#xff09; 1、污点&#xff08;Taints&#xff09;2、容忍度&#xff08;Tolerations&#xff09;3、示例演示-测试污点的具体应用场景3.1 给节点打污点&…

HarmonyOS开发案例:【智能煤气检测】

样例简介 智能煤气检测系统通过实时监测环境中烟雾浓度&#xff0c;当一氧化碳浓度超标时&#xff0c;及时向用户发出警报。在连接网络后&#xff0c;配合数字管家应用&#xff0c;用户可以远程配置智能煤气检测系统的报警阈值&#xff0c;远程接收智能煤气检测系统报警信息。…

多轴机械臂/正逆解/轨迹规划/机器人运动学/Matlab/DH法 学习记录02——机械臂几何法与DH表示法

系列文章目录 本科毕设正在做多轴机械臂相关的内容&#xff0c;这里是一个学习机械臂运动学课程的相关记录。 如有任何问题&#xff0c;可发邮件至layraliufoxmail.com问询。 1. 数学基础 2. 机械臂几何法与DH表示法 文章目录 系列文章目录一、手臂几何法1.机械手臂2.机械手臂…

4.配置USART串口实现printf打印

通过TTL转USB实现电脑和单片机连通,是我们调试必不可少的工具 查看原理图,使用USART1,它们的TX和RX分别在PA9和PA10 新建Usart.c存放串口模块的初始化 这段代码是复制了正点原子的工程,添加到前面 #if SYSTEM_SUPPORT_OS #include "includes.h" //ucos 使用 …