如何实现基于场景的接口自动化测试用例?
自动化本身是为了提高工作效率,不论选择何种框架,何种开发语言,我们最终想实现的效果,就是让大家用最少的代码,最小的投入,完成自动化测试的工作。
基于这个想法,我们的接口自动化测试思路如下:
1.不变的内容全部通过配置化来实现,比如:脚本执行的环境、请求的 HOST、URL 路径、测试数据等;
2.环境和数据关联变更:依据不同的环境,选择不同的配置及对应的测试数据;
3.抽取公共方法,避免冗余代码;
4.场景化的用例,实现可配置化;
5.数据驱动。
1.问题
在做自动化的过程中,不能只考虑单接口的脚本,也要考虑场景化的用例。场景化的用例不需要每个步骤都去校验所有的数据,可能更多看重串联后的最终效果。
那什么是场景用例?
其实就是多个接口组成的业务场景,常规写代码的做法是,先调用接口1,验证结果, 再调用接口2,再继续接口3,… 等等;在测试场景中,可能只是各个接口的入参不一样,或者是调用的接口不一样。这样代码写起来就会冗余。
比如:
def test_01(self):# step 01result1 = PackDemo().getTest()assert result1 == 4# step02result2 = PackDemo2().getTest2("name")assert result2 == 'name'# step03result3 = DemoApi().getTest()assert result3 == 2
这样的用例,对于简单的接口没什么问题,但是对于复杂的接口,校验逻辑比较多,或者入参比较多,实现的方式就过于单一了。且不同场景的话,每个都要更改调用的步骤和返回值,场景越多冗余越多。
如果使用配置化的方式,每次从配置文件中动态加载配置的场景用例, 而且能够做到加载后做对应的断言,那该多好。
怎么做呢?咱们看看一些核心的实现。
2.方案
2.1 项目结构
项目结构如下:
采用当前比较流行的 Python + Pytest + Allure 来实现,具体结构不做展开。
2.2 场景用例的配置数据
# test_scenario.json
{"test_01": {"step_1": { ---- 步骤节点名称,可自定义"packagePath": "api", --- 这个步骤要运行的方法所属类的包路径"class": "DemoApi", --- 这个步骤要运行的方法所属类名称"method": "getTest", --- 这个步骤要运行的方法名称"request": null, ---这个步骤运行的方法入参"response": 2, ---这个步骤运行的结果,可以是一个值,或者对象"verify": { --- 数据校验的节点"type": 1, ---数据校验的类型"keys": null ---如果是校验的特定字段,这里需要输入部分校验的字段}},"step_2": {"packagePath": "api.demo","class": "PackDemo","method": "getTest2","request": "request -> name","response": 6,"verify": {"type": 1,"keys": null}},"step_3": {"packagePath": "api.demo","class": "PackDemo2","method": "getTest3","request": {"name": "param-name","num_list": ["a", "b", "c"]},"response": 8,"verify": {"type": 1,"keys": null}}}
}
2.3 动态加载类
在我们配置了以上的测试场景的数据后,我们希望在用例执行的过程中,通过获取我们的配置,能够动态的加载数据文件中提到的方法,并执行对应的方法,那这个过程的实现我们主要通过如下的动态加载类来实现。
# DynamicLoad.py
# 部分主要的摘录如下def __load_module(self):"""加载对应路径下的模块:param package_path: 包路径:param class_name: 类名称:return:"""return importlib.import_module("." + self.class_name, package=self.package_path)def __getClassInstance(self):"""加载对应的模块下的类,并返回对应类的实例 :param module_name: 对应的模块:param class_name::return:"""self.my_module = self.__load_module()self.my_class = getattr(self.my_module, self.class_name)()return self.my_classdef execMethod(self, method, *args):"""加载对应类下的方法 :param instance: 对应的实例:param method: 要执行的方法:return:"""result = getattr(self.__getClassInstance(), method)(*args)return result
有了以上动态加载的方法后,在执行场景用例时,依据上述的方法,就可以执行测试文件中提到的方法。
2.4 场景分析类
在场景用例的测试数据中,除了需要解析需要执行的类、方法外,还要解析文件中涉及到的出入参及数据比对方式,因此,这里还需要一个场景分析类,来解析数据文件中关于具体执行过程的配置。
#ScenariosAnalyze.pydef analyse_exe_scenario(self, case_data):step_result = {}summary = Truefor i in case_data:instance = DynamicLoad(case_data[i]['packagePath'], case_data[i]['class'])if case_data[i]['request'] is not None:result = instance.execMethod(case_data[i]['method'], case_data[i]['request'])else:result = instance.execMethod(case_data[i]['method'])if case_data[i]['verify'] is not None:compare_type = case_data[i]['verify']['type']keys = case_data[i]['verify']['keys']step_compare_result = DataCompare().compare_type(compare_type=compare_type, actual=result,expect=case_data[i]['response'], keys=keys)if not step_compare_result:summary = Falsestep_result[i] = step_compare_resultstep_result['summary'] = summaryreturn step_result
2.5 用例实现
# @File : test_scenario.pyclass TestScenario:@allure.story('场景用例01')@allure.severity(allure.severity_level.BLOCKER)@pytest.mark.smokedef test_01(self):result = Nonecase_data = self.test_data_json['test_01']result = self.scenario_analyze.analyse_exe_scenario(case_data)assert result['summary'] is True
通过上述简单的脚本调用,就可以完成一个场景用例的测试了。
3.小结
以上就是场景用例配置化的实现思路。
它的优点是:
1.配置化: 一切固定不变的内容全部配置化,最终达到:一个环境配置文件,一套脚本,几套测试数据,依据环境的不同选择不同的测试数据执行对应的测试脚本;
2.门槛低:因为配置化,测试同学只要把测试数据文件中的关键节点配置好,然后在脚本中写下调用方法,就完成用例编写了;
3.好扩展:在后续的实现中,可以将这些配置全部页面化,包括环境、数据、脚本,达到无代码开发的目的;
缺点当然是不够灵活,所以没有完美的方案,只有合适的,以上,仅供大家参考。
【下面是我整理的2023年最全的软件测试工程师学习知识架构体系图】
一、Python编程入门到精通

二、接口自动化项目实战
三、Web自动化项目实战

四、App自动化项目实战
五、一线大厂简历

六、测试开发DevOps体系
七、常用自动化测试工具

八、JMeter性能测试
九、总结(尾部小惊喜)
生命不息,奋斗不止。每一份努力都不会被辜负,只要坚持不懈,终究会有回报。珍惜时间,追求梦想。不忘初心,砥砺前行。你的未来,由你掌握!
生命短暂,时间宝贵,我们无法预知未来会发生什么,但我们可以掌握当下。珍惜每一天,努力奋斗,让自己变得更加强大和优秀。坚定信念,执着追求,成功终将属于你!
只有不断地挑战自己,才能不断地超越自己。坚持追求梦想,勇敢前行,你就会发现奋斗的过程是如此美好而值得。相信自己,你一定可以做到!
相关文章:

如何实现基于场景的接口自动化测试用例?
自动化本身是为了提高工作效率,不论选择何种框架,何种开发语言,我们最终想实现的效果,就是让大家用最少的代码,最小的投入,完成自动化测试的工作。 基于这个想法,我们的接口自动化测试思路如下…...

SAP 开发编辑界面-关闭助手
打开关闭助手时的开发界面如下: 关闭关闭助手后的界面如下: 菜单栏: 编辑--》修改操作--》关闭助手...

【el-image图片查看时 样式穿透表格问题】
element-ui el-image图片查看 样式混乱 解决方式 ::v-deep(.el-table__cell) {position: static !important; // 解决el-image 和 el-table冲突层级冲突问题 }加个样式即可...
GPT带我学-设计模式-模板模式
1 请你给我介绍一下设计模式中的模板模式 模板模式是一种行为设计模式,它定义了一个算法的骨架,将一些步骤的具体实现延迟到子类中。模板模式允许子类重新定义算法的某些特定步骤,而不需要改变算法的结构。 模板模式由以下几个角色组成&…...

Windows下调试UEFI程序:Visual Studio调试
以edk2\MdeModulePkg\Application\HelloWorld这个项目作为调试目标。 1. 使用VS2017建立Makefile工程 VS2017, 新建 project,取名X64dbg_vs。 Visual C > Other > Makefile Project, 注意项目路径为HelloWord程序路径。 随便填写config中的字符串ÿ…...

Vue中监听路由参数变化的几种方式
目录 一. 路由监听方式: 通过 watch 进行监听 1. 监听路由从哪儿来到哪儿去 2. 监听路由变化获取新老路由信息 3. 监听路由变化触发方法 4. 监听路由的 path 变化 5. 监听路由的 path 变化, 使用handler函数 6. 监听路由的 path 变化,触发method…...
angular——子组件如何接收父组件的动态传值
开发过程中,父组件给子组件传值的情况很常见,今天我们就来聊聊父组件给子组件传值可能会发生哪些意外,什么情况下子组件无法接收到父组件最新的传值; 传值情况: 基本数据类型:父组件给子组件传递 基本数据…...
php 桥接模式
一,桥接模式,是结构设计模式的一种,其将抽象部分和实现部分分离开来,使两部分可以独立的进行修改,提高系统的灵活性。在桥接模式中,需要定义一个抽象类和一个实现类,通过将实现类注入到抽象类中…...
Android 13 Hotseat定制化修改——004 hotseat布局位置
目录 一.背景 二.原生hotseat布局位置 三.修改Hotseat布局位置 一.背景 由于需求是需要自定义修改Hotseat,所以此篇文章是记录如何自定义修改hotseat的,应该可以覆盖大部分场景,修改点有修改hotseat布局方向,hotseat图标数量,hotseat图标大小,hotseat布局位置,hotseat…...

海外版金融理财系统源码 国际投资理财系统源码 项目投资理财源码
海外版金融理财系统源码 国际投资理财系统源码 项目投资理财源码...
洛谷P1162 - 填涂颜色
题目描述 由数字 0 0 0 组成的方阵中,有一任意形状闭合圈,闭合圈由数字 1 1 1 构成,围圈时只走上下左右 4 4 4 个方向。现要求把闭合圈内的所有空间都填写成 2 2 2。例如: 6 6 6\times 6 66 的方阵( n 6 n6 n6&…...
设计模式十一:外观模式(Facade Pattern)
外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用于访问系统中的一组复杂子系统。外观模式通过将复杂子系统的接口封装在一个高层接口中,简化了客户端与子系统之间的交互,使得客户…...
GIS和倾斜摄影的关系?
GIS(地理信息系统)和倾斜摄影是两种在地理空间数据处理和分析中扮演重要角色的技术。但是我们总是会分不清二者,本文就带大家从不同角度了解二者之间的关系。 概念 GIS是一种用来捕获、存储、分析和展示地理空间数据的技术,它可以…...

【CI/CD】图解六种分支管理模型
图解六种分支管理模型 任何一家公司乃至于一个小组织,只要有写代码的地方,就有代码版本管理的主场,初入职场,总会遇到第一个拦路虎 git 管理流程,但是每一个企业似乎都有自己的 git 管理流程,倘若我们能掌握…...

LeetCode105. 从前序与中序遍历序列构造二叉树
105. 从前序与中序遍历序列构造二叉树 文章目录 [105. 从前序与中序遍历序列构造二叉树](https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)一、题目二、题解 一、题目 给定两个整数数组 preorder 和 inorder ,其中 preo…...

编码技巧——Sentinel的blockHandler与fallback
本文介绍Sentinel的blockHandler与fallback的区别,背景是:发生限流时,配置的sentinel的blockhandler没有生效而fallback生效了;排查原因,从而给出Sentinel配置异常降级和限流降级的代码写法; 在查看源码前…...

最新成果展示:GaN基Micro-LED热学模型数据库的开发及应用
由于GaN基Micro-LED表面积-体积比增加,其在热学方面的性质有别于大尺寸的LED,如缺陷复合导致的热效应将在发光区域中产生诸多“热”点,导致发光波长不均匀,这将影响后期显示系统的成像稳定性。针对上述问题,天津赛米卡…...

【Vue3】动态组件
动态组件的基本使用 动态组件(Dynamic Components)是一种在 Vue 中根据条件或用户输入来动态渲染不同组件的技术。 在 Vue 中使用动态组件,可以使用 元素,并通过 is 特性绑定一个组件的名称或组件对象。通过在父组件中改变 is 特…...
Java超级玛丽小游戏制作过程讲解 第五天 创建并完成常量类04
//加载障碍物 try {obstacle.add(ImageIO.read(new File(path"brick.png")));obstacle.add(ImageIO.read(new File(path"soil_up.png")));obstacle.add(ImageIO.read(new File(path"soil_base.png"))); } catch (IOException e) {e.printStackTr…...
设置浏览器兼容
浏览器兼容 css兼容 cursor定义手型 Firefox不支持hand,IE支持pointer 解决方法:统一使用pointercss透明 IE:filter:progid:DXImageTransform.Microsoft.Alpha(style0,opacity60) Firefox:opacity:0.6 解决…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...