如何实现基于场景的接口自动化测试用例?

自动化本身是为了提高工作效率,不论选择何种框架,何种开发语言,我们最终想实现的效果,就是让大家用最少的代码,最小的投入,完成自动化测试的工作。

基于这个想法,我们的接口自动化测试思路如下:

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性能测试 

九、总结(尾部小惊喜)

生命不息,奋斗不止。每一份努力都不会被辜负,只要坚持不懈,终究会有回报。珍惜时间,追求梦想。不忘初心,砥砺前行。你的未来,由你掌握!

生命短暂,时间宝贵,我们无法预知未来会发生什么,但我们可以掌握当下。珍惜每一天,努力奋斗,让自己变得更加强大和优秀。坚定信念,执着追求,成功终将属于你!

只有不断地挑战自己,才能不断地超越自己。坚持追求梦想,勇敢前行,你就会发现奋斗的过程是如此美好而值得。相信自己,你一定可以做到!

                                     

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

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

相关文章

软件设计师(七)面向对象技术

面向对象: Object-Oriented, 是一种以客观世界中的对象为中心的开发方法。 面向对象方法有Booch方法、Coad方法和OMT方法等。推出了同一建模语言UML。 面向对象方法包括面向对象分析、面向对象设计和面向对象实现。 一、面向对象基础 1、面向对象的基本…

【数据结构与算法】二叉排序树(BST)

二叉排序树(BST) 需求: 给你一个数列{7,3,10,12,5,1,9},要求能够高效的完成对数据的查询和添加。 解决方案分析 使用数组 数组未排序,优点:直接在数组尾添加,速度快。缺点:查找速…

[C++项目] Boost文档 站内搜索引擎(3): 建立文档及其关键字的正排 倒排索引、jieba库的安装与使用...

之前的两篇文章: 第一篇文章介绍了本项目的背景, 获取了Boost库文档 🫦[C项目] Boost文档 站内搜索引擎(1): 项目背景介绍、相关技术栈、相关概念介绍…第二篇文章 分析实现了parser模块. 此模块的作用是 对所有文档html文件, 进行清理并汇总 🫦[C项目] …

Spring Boot整合ES的两种方式

使用Spring Data Elasticsearch Starter 在Spring Boot中整合Elasticsearch的方式之一是使用Elasticsearch的官方Spring Data Elasticsearch Starter。该Starter提供了对Elasticsearch的高级集成,简化了配置和管理Elasticsearch客户端。 下面是使用Spring Data E…

【C++】智能指针

一、为什么要智能指针 下面我们先分析下面这段程序有没有什么内存方面的问题? int Div(int a, int b) {if (b 0)throw invalid_argument("除0错误");elsereturn a / b; } void Func() {// 1、如果 p1 这里 new 抛异常会如何?// 2、如果 p2 …

【C++从0到王者】第十六站:stack和queue的使用

文章目录 一、stack的使用1.stack的介绍2.stack的使用 二、queue的使用1.queue的护额晒2.queue的使用 三、stack和queue相关算法题1.最小栈2.栈的压入、弹出序列3.逆波兰表达式4.两个栈实现一个队列5.用两个队列实现栈6.二叉树的层序遍历1.双队列2.用一个变量levelSize去控制 7…

K8S系列文章 之 编写自动化部署K8S脚本

介绍 通过ansible脚本shell实现自动化部署k8s基础集群(v1.25.0) 部署结构 1. 通过二进制部署包镜像安装k8s集群、目录etcd节点只支持1-3个节点、最多三个etcd节点 2. 因k8s版本相对较新、需要升级内核来支持后台程序、当前版本只支持Cento7,内核版本(5.19.4-1.el7…

ffmpeg+nginx实现rtsp协议摄像头web端播放

ffmpegnginx实现rtsp协议摄像头web端播放 环境准备准备nginx环境添加rtmp模块添加hls转发 使用ffmpeg,将摄像头rtsp转为rtmp并推送到nginxVLC播放验证 环境准备 nginx(需要安装rtmp模块)ffmpeg 6.0vlc播放器(本地播放验证&#x…

大数据课程H2——TELECOM的电信流量项目实现

文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解TELECOM项目的数据收集; ⚪ 了解TELECOM项目的数据清洗; ⚪ 了解TELECOM项目的数据导出; ⚪ 了解TELECOM项目的数据可视化&…

观察者模式(C++)

定义 定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。 ——《设计模式》GoF 使用场景 一个对象(目标对象)的状态发生改变,所有的依赖对…

SpringBoot第33讲:SpringBoot集成ShardingJDBC - 基于JPA的读写分离

SpringBoot第33讲:SpringBoot集成ShardingJDBC - 基于JPA的读写分离 本文是SpringBoot第33讲,主要介绍分表分库,以及SpringBoot集成基于 ShardingJDBC 的读写分离实践 文章目录 SpringBoot第33讲:SpringBoot集成ShardingJDBC - 基…

uni-app:实现点击按钮出现底部弹窗(uni.showActionSheet+自定义)

一、通过uni.showActionSheet实现底部选择 效果 代码 <template><view><button click"showActionsheet">点击打开弹窗</button></view> </template><script> export default {methods: {showActionsheet() {uni.showAct…

消息队列项目(2)

我们使用 SQLite 来进行对 Exchange, Queue, Binding 的硬盘保存 对 Message 就保存在硬盘的文本中 SQLite 封装 这里是在 application.yaml 中来引进对 SQLite 的封装 spring:datasource:url: jdbc:sqlite:./data/meta.dbusername:password:driver-class-name: org.sqlite.…

Python 中的机器学习简介:多项式回归

一、说明 多项式回归可以识别自变量和因变量之间的非线性关系。本文是关于回归、梯度下降和 MSE 系列文章的第三篇。前面的文章介绍了简单线性回归、回归的正态方程和多元线性回归。 二、多项式回归 多项式回归用于最适合曲线拟合的复杂数据。它可以被视为多元线性回归的子集。…

APP外包开发的学习流程

学习iOS App的开发是一项有趣和富有挑战性的任务&#xff0c;是一个不断学习和不断进步的过程。掌握基础知识后&#xff0c;不断实践和尝试新的项目将使您的技能不断提升。下面和大家分享一些建议&#xff0c;可以帮助您开始学习iOS App的开发。北京木奇移动技术有限公司&#…

DAY02_Spring—第三方资源配置管理Spring容器Spring注解开发Spring整合Mybatis和Junit

目录 一 第三方资源配置管理1 管理DataSource连接池对象问题导入1.1 管理Druid连接池1.2 管理c3p0连接池 2 加载properties属性文件问题导入2.1 基本用法2.2 配置不加载系统属性2.3 加载properties文件写法 二 Spring容器1 Spring核心容器介绍问题导入1.1 创建容器1.2 获取bean…

软件架构师思维塑造

一、软件系统设计的六项原则 1、单一职责原则&#xff08;Single Responsibility Principle&#xff09; 2、开闭原则&#xff08;Open Closed Principle&#xff09; 3、里氏替换原则&#xff08;Liskov Substitution Principle&#xff09; 4、迪米特法则&#xff08;Law of …

微服务 云原生:基于 Gogs + Drone 进行项目 CI/CD

传统构建部署 以一个简单的前后端项目来说&#xff0c;分别编写前后端的 Dockerfile 文件并构建镜像&#xff0c;然后编写 docker-compose.yml 构建部署&#xff0c;启动运行。 一个简单的例子&#xff1a; 前端&#xff1a; 项目名&#xff1a;kubemanagement-web技术栈&am…

Java中Date方法详解

先进行专栏介绍 本专栏是自己学Java的旅途&#xff0c;纯手敲的代码&#xff0c;自己跟着黑马课程学习的&#xff0c;并加入一些自己的理解&#xff0c;对代码和笔记 进行适当修改。希望能对大家能有所帮助&#xff0c;同时也是请大家对我进行监督&#xff0c;对我写的代码进行…

eeglab(自用)

目录 1.加载、显示数据 2.绘制脑电头皮图 3.绘制通道光谱图 4.预处理工具 5.ICA去除伪迹 5. 提取数据epoch 1.加载、显示数据 观察事件值(Event values)&#xff1a;该数据集中包含2400个事件&#xff0c;每个事件指定了EEG.event结构的字段Type(类型)、position(位置)和…