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

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

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

用例依赖的问题

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

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

正确的做法

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

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.hqwc.cn/news/623692.html

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

相关文章

数据结构——栈(C++实现)

数据结构——栈 什么是栈栈的实现顺序栈的实现链栈的实现 今天我们来看一个新的数据结构——栈。 什么是栈 栈是一种基础且重要的数据结构&#xff0c;它在计算机科学和编程中扮演着核心角色。栈的名称源于现实生活中的概念&#xff0c;如一叠书或一摞盘子&#xff0c;新添加…

sort用法

前两个参数传范围&#xff0c;可以是迭代器也可以是指针&#xff0c;最后传比较方法。该方法判断cmp的第一个参数是否在第二个参数之前&#xff0c;比如这里想从小到大排序&#xff0c;x为小的时候在前&#xff0c;所以当x<y的时候我们返回1.

材料物理 笔记-6

原内容请参考哈尔滨工业大学何飞教授&#xff1a;https://www.bilibili.com/video/BV18b4y1Y7wd/?p12&spm_id_frompageDriver&vd_source61654d4a6e8d7941436149dd99026962 或《材料物理性能及其在材料研究中的应用》&#xff08;哈尔滨工业大学出版社&#xff09; 文…

再也不想用丑东西了!一个高颜值的备忘录,分享给你们【文末领源码】

谁工作中不得有点丢三落四的&#xff0c;但是被老大点名批评确实有点过不去了&#xff0c;提醒小伙伴们把必要的事情挂出来&#xff0c;同事说虽然已经有一款系统&#xff0c;但展示的不好看&#xff0c;根本不想用&#xff0c;于是找到了一款颜值还不错的备忘录工具 -- memo …

前端开发框架BootStrap

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl BootStrap概述 Bootstrap是一个开源的前端框架&#xff0c;它由Twitter的设计师和开发者创建并维护。Bootstrap提供了许多现成的Web组件&#xff0c;可帮助开发者快速设计和…

免单优选电商模式:激发购买欲望的创新销售策略

免单优选电商模式&#xff0c;作为一种创新的销售策略&#xff0c;其核心在于通过价格优惠、渐进式激励和社交网络结合&#xff0c;有效刺激消费者的购买行为&#xff0c;进而推动销售业绩的快速增长。 一、合法合规&#xff0c;规避多层次奖励风险 该模式坚持合法合规的运营原…

【Web】VS Code 插件

专栏文章索引&#xff1a;Web 有问题可私聊&#xff1a;QQ&#xff1a;3375119339 目录 一、安装步骤 二、插件 1.Chinese (Simplified) (简体中文) 2.open in browser 3.vscode-icons 4.Live Server 5.Live Server Preview 6.翻译(英汉词典) 一、安装步骤 点击 “扩…

R-Tree的概念

R-Tree可以称作空间索引的基石&#xff0c;目前流行的时空索引架构都是基于R-Tree衍生而来。 R-Tree的概念 R-Tree 主要用于索引多维信息&#xff08;如地理点坐标、矩形或多边形&#xff09;的一种数据结构。R -Tree是由Guttman在1984年提出的&#xff0c;在理论和应用上都有…

软考-系统集成项目管理中级--进度管理(输入输出很重要!!!本章占分较高,着重复习)

本章历年考题分值统计(16年11月及以后按新教材考的&#xff09; 本章重点常考知识点汇总清单(学握部分可直接理解记忆) 12、参数估算:参数估算是一种基于历史数据和项目参数&#xff0c;使用某种算法来计算成本或持续时间的估算技术。参数估算是指利用历史数据之间的统计关系和…

Turbo并发插件使用说明

文章目录 一、安装Turbo Intruder插件1. 安装方式12. 安装方式2二、并发短信验证码轰炸示例一、安装Turbo Intruder插件 1. 安装方式1 在BurpSuite的扩展里的BApp商店可直接安装 打开BurpSuite,点击扩展点击BApp商店搜索turbo Intruder选择Turbo Intruder插件点击安装2. 安装…

5_vscode+valgrind+gdb调试程序

需求 项目程序, 读取串口数据, 出现程序崩溃问题valgrind 可以调试定位内存问题: 内存泄漏,非法地址访问,越界访问等内存问题vscode gdb 可视化调试效果, 比命令行简单快捷很多期望使用vscode valgrind gdb 调试程序内存异常, 崩溃退出的问题 环境准备 sudo apt install v…

(GPT-PLUS,RawChat,choose-car,Kimi,智谱清言)分享5个好用的ChatGPT

目录 1、GPT-PLUS拼车 2、RawChat公益站点 3、GPT-PLUS共享 4、choose-car 5、AI提示器 6、Kimi.ai - 帮你看更大的世界 7、智谱清言 1、GPT-PLUS拼车 https://home.topai.vip/list GPT-PLUS拼车 TOPAI宇宙 | Link3 2、RawChat公益站点 https://sharedchat.cn/ 3、GPT-PLUS共享…