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

在 seldom 3.4.0 版本实现了该功能。

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

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

用例依赖的问题

•用例的依赖对于的执行顺序有严格的要求,比如让被依赖的方法先执行。•一旦使用用例依赖,依赖的用例就无法单独执行了,按照用例的设计原则,每条用例都应该独立执行。

正确的做法

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

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

类内部方法调用

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

import seldomfrom seldom.testdata import get_md5from seldom.utils import cache, dependent_func

class DependentTest(seldom.TestCase):
    @staticmethod    def 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 = 35e0ff9c4cba89998dda8255d0eb54082023-11-15 23:26:36 | INFO     | cache.py | 💾 Get cache data: user_login = 35e0ff9c4cba89998dda8255d0eb5408token 35e0ff9c4cba89998dda8255d0eb5408ok
----------------------------------------------------------------------Ran 1 test in 0.005s
OK2023-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
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036【暗号:csdn999】

外部类方法依赖

•创建依赖方法

# common.pyfrom seldom.testdata import get_md5

class Login:
    @staticmethod    def account_login(username, password):        """        模拟用户&密码登录,获取登录token        """        return get_md5(username+password)

login=Login()

•用例引用依赖方法​​​​​​​

import seldomfrom seldom.utils import cache, dependent_funcfrom 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.pyfrom seldom.testdata import get_md5, get_intfrom seldom.utils import cache, dependent_func
class Login:
    @staticmethod    def 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 seldomfrom seldom.utils import cache, dependent_funcfrom common import DepFunc

class 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.pyfrom seldom.testdata import get_int, username

class DataFunc:
    @staticmethod    def get_name():        return username(language="zh")
    @staticmethod    def get_age():        return get_int(1, 99)

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

import seldomfrom seldom.utils import cache, dependent_funcfrom common import DataFunc

class 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 seldomfrom seldom import datafrom seldom.testdata import get_md5from seldom.utils import cache, dependent_func

class DependentTest(seldom.TestCase):
    @staticmethod    def 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() 被执行过一次后,第二次则不需要重复执行,直接返回结果。

References

[1] aomaker: https://github.com/ae86sen/aomaker

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走!

软件测试面试文档

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Dart笔记:glob 文件系统遍历

Dart笔记 文件系统遍历工具&#xff1a;glob 模块 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/13442…

机器学习笔记 - 隐马尔可夫模型的简述

隐马尔可夫模型是一个并不复杂的数学模型,到目前为止,它一直被认为是解决大多数自然语言处理问题最为快速、有效的方法。它成功地解决了复杂的语音识别、机器翻译等问题。看完这些复杂的问题是如何通过简单的模型得到描述和解决,我们会由衷地感叹数学模型之妙。 人类信息交流…

Pandas 将DataFrame中单元格内的列表拆分成单独的行

使用 explode 函数 import pandas as pddata {month: [1, 2],week: [[i for i in range(2)], [i for i in range(3)]]} df pd.DataFrame(data) print(df)df df.explode(week) print(df)

【数据结构】栈与队列面试题(C语言)

我们再用C语言做题时&#xff0c;是比较不方便的&#xff0c;因此我们在用到数据结构中的某些时只能手搓或者Ctrlcv 我们这里用到的栈或队列来自栈与队列的实现 有效的括号 有效的括号&#xff0c;链接奉上。 解题思路&#xff1a; 先说结论&#xff1a; 因为我们是在讲栈与…

[C国演义] 哈希的使用和开闭散列的模拟实现

哈希的使用和开闭散列的模拟实现 1. 使用1.1 unordered_map的接口1.2 unordered_set的接口 2. 哈希底层2.1 概念2.2 解决哈希冲突 3. 实现3.1 开放寻址法3.2 拉链法 1. 使用 1.1 unordered_map的接口 构造 void test1() {// 空的unordered_map对象unordered_map<int, in…

【Proteus仿真】【Arduino单片机】LM35温度计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用PCF8574、LCD1602液晶、LM35传感器等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示传感器检测温度。 二、软件设计 /* 作者&a…

Jmeter 吞吐量Per User作用

第一点&#xff1a;Per User仅在Total Execution时生效 第二点&#xff1a;Per User 选中后 聚合报告中将统计的的样本数将变成线程组配置的线程数*吞吐量控制器配置的执行样本数量&#xff08;前提是线程组配置执行接口的次数线程数*循环数 大于吞吐量控制器配置的执行样本数…

【脑与认知科学】【n-back游戏】

请参考课堂内容&#xff0c;设计一种测试工作记忆的实验方法&#xff0c;并选择三位同学作为被试测试工作记忆。请画出实验流程图&#xff0c;叙述实验测试目标&#xff0c;并分析实验结果。 举例&#xff1a;一般我们选择n_back来测试对数字或字母的记忆&#xff0c;选择色块实…

Python字典六种类型概述

1. 引言 看到这个标题&#xff0c;你可能会觉得奇怪&#xff0c;事实上在Python的标准库中共有6种字典类型&#xff01;在某些情形下&#xff0c;你可能会觉得标准的Python字典dict&#xff0c;并不能完全符合你的需求。在本文中&#xff0c;我们将讨论Python中其他5个鲜为人知…

【火炬之光-魔灵装备】

文章目录 装备天赋追忆石板技能魂烛刷图策略 装备 头部胸甲手套鞋子武器盾牌项链戒指腰带神格备注盾牌其余的装备要么是召唤物生命&#xff0c;要么是技能等级&#xff0c;鞋子的闪电技能等级加2不是核心&#xff0c;腰带的话主要是要冷却有冷却暗影的技能是不会断的&#xff…

快速提高编码生产力——中国用户如何使用Jetbrains内置的AI助手

文章目录 安装AI助手插件怎么在国内使用改Jetbrains账户Country特殊工具安排上系统设置代理IDE设置代理 使用案例 安装AI助手插件 此功能依赖于AI Assistant插件&#xff0c;您需要安装并启用该插件。 按打开 IDE 设置&#xff0c;然后选择插件。CtrlAltS打开Marketplace选项…

pyqt designer的版本问题

之前我的电脑Windows11 python3.12上安装好了pyqt6后&#xff0c;安装不了pyqt6-tools&#xff0c;导致不能使用designer设计师服务。经过摸索&#xff0c;然来只需要安装qt-tools就够了。qt-tools在plugin包里。比如文章顶部的资源包&#xff0c;下载下来直接使用pip安装该whl…

Linux inotify 文件监控

Linux 内核 2.6.13 以后&#xff0c;引入了 inotify 文件系统监控功能&#xff0c;通过 inotify 可以对敏感目录设置事件监听。这样的功能被也被包装成了一个文件监控神器 inotify-tools。 使用 inotify 进行文件监控的过程&#xff1a; 创建 inotify 实例&#xff0c;获取 i…

小命令,大世界

Linux是一个大系统&#xff0c;功能丰富&#xff0c;好比是一台巨型机器&#xff0c;而命令&#xff0c;就是这台机器的操作台。要想控制好这台机器&#xff0c;用好这台机器&#xff0c;就得会看仪表&#xff0c;会操作各种按钮。《Linux常用命令自学手册》就是介绍如何操作这…

Linux上编译和安装SOFA23.06

前言 你可以直接使用编译安装好的SOFA版本Installing from all-included binaries (v23.06.00)&#xff1a; 如果你想自己编译&#xff0c;可以看我下面写的内容&#xff0c;不过绝大多数是从官网来的&#xff0c;如果和官网有出入&#xff0c;建议还是以官网为准。 在Linux下…

csapp深入理解计算机系统 bomb lab(1)phase_1

实验目的&#xff1a;进一步了解机器级代码&#xff0c;提高汇编语言、调试器和逆向工程等方面原理与技能的掌握。 实验环境&#xff1a;C、linux 实验获取&#xff1a;进入csapp官网&#xff0c;点击linux/x86-64 binary bomb下载实验压缩包。 实验说明&#xff1a;一共有6…

下一代搜索引擎会什么?

现在是北京时间2023年11月18日。聊一聊搜索。 说到搜索&#xff0c;大家首先想到的肯定是谷歌&#xff0c;百度。我把这些定义成上一个时代的搜索引擎。ChatGPT已经火热了有一年的时间了&#xff0c;大家都认为Ai搜索是下一代的搜索。但是AI搜索&#xff0c;需要的是很大算力&a…

Wireshark TS | 应用传输缓慢问题

问题背景 沿用之前文章的开头说明&#xff0c;应用传输慢是一种比较常见的问题&#xff0c;慢在哪&#xff0c;为什么慢&#xff0c;有时候光从网络数据包分析方面很难回答的一清二楚&#xff0c;毕竟不同的技术方向专业性太强&#xff0c;全栈大佬只能仰望&#xff0c;而我们…

前端JS 使用input完成文件上传操作,并对文件进行类型转换

使用input实现文件上传 // 定义一个用于文件上传的按钮<input type"file" name"upload1" />// accept属性用于定义允许上传的文件类型&#xff0c; onchange用于绑定文件上传之后的相应函数<input type"file" name"upload2"…