接口测试 - 从0不到1的心路历程

news2024/11/24 1:43:02

我是一名做了三年测试的tester,2020年以功能测试工程师的身份入职北京一家医疗培训公司,入职后为了提高测试效率,接触到接口测试,以下是从零到现在 (还有很大完善的空间,所以不能算是1) 的一些心路历程。

做接口测试的动机

于公司业务和团队现状而言,团队中仅我一名测试,随着产品功能日益丰富,导致回归测试任务量越来越大,紧靠人工回归,效率低,质量低,所以自动化测试势在必行。

于个人职业发展路径而言,每天点点点,看似很忙,但除了对业务流程越来越熟练之外,硬技能长进很慢,要想把测试这条路走宽走远,主动求变是必须的,站在功能测试工程师的角度看职业发展方向,无非就是安全测试、性能测试、自动化测试以及管理方向,刚好公司业务所需,所以决定先从自动化测试入手。

起步阶段,选择JMeter

我认为打算做一件事情之前,如果准备过多,往往会阻碍起步的脚步,过犹不及,不如稍作准备就马上抛竿,实践一下鱼塘里有没有口儿。所以我选择了上手比较容易的JMeter,从接口自动化开始突破。当时手握《全栈性能测试修炼宝典 JMeter实战》这本经典工具书,参考网上优秀的实战经验帖,很快就搭建出了一套200条case的脚本,脚本中尽可能的提取公共变量,解决接口依赖问题。

图片

弃用JMeter做接口自动化测试

随着 case 越来越多,发现一旦有接口变更,维护起来的难度极大 (极容易眼花缭乱),有一次因为入参的值多了一个空格,导致我整整找了3个多小时,当发现原因时直接崩溃 (具体是哪个参数值想不起来了,举个例子:正确: 14 t r a i n C e n t e r I d , 错 误 : {14trainCenterId},错误: 14trainCenterId{ 14trainCenterId}),就因为在14面前多了一个空格,我在200 多条case,几千参数值中找了整整一下午,至此,决定放弃JMeter。

其实JMeter不适合在团队中做接口自动化测试的另一个重要原因是多人合作编写一个脚本并不是很方便,但介于当时团队中只有我一个人,所以没切实的体会过这个缺点。

虽然弃用JMeter,但在编写接口测试期间,脑子里也形成了一套接口测试case 的编写方法论,比如接口测试case设计需要考虑正常情况 (必填项必填,参数之间的组合,参数值的遍历等等),异常情况 (必填参数参数值为空、为异常值、索性连参数都不写等等),其实接口 case 的设计和业务功能测试 case 设计时的思路差不多,唯一区别可能是手动点点点时一些参数的输入被大前端限制住了,但是接口测试就可以随便传参。

尝试使用Python+unittest+requests

弃用工具那就只好选择编程语言了,当时选择Python其实没那么多高大上的理由,单单是因为看到了那句"人生苦短…",再加上在自动化测试这方面Python的呼声也很高,我自己也倾向做事尽可能的立竿见影,所以没有考虑Java。

要单说仅仅让Python脚本跑起来,也许只需要学一些基础的语法,迟则三五天的事情,再选择一个测试框架,当时选择的是这样的组合:Python+unittest+requests。前期照葫芦画瓢一边学 Python 语法,一边学习测试框架。很快就写出了一套和之前JMeter一样效果的测试脚本(虽然整个项目就仅有两个文件:test_.py 和 run.py,虽然简陋,但是能跑,入门学习是够了的)。至此也算是入了道儿了。

因为我是刚刚起步,团队中也没有这方面的前辈可以指点,所以几乎是摸着石头过河,走了很多弯路 (也许现在走的路也不直),但我每积累一段时间我都会停下来总结思考是不是需要重构,并不会随着思维惯性 瓷蹦蹦 的复制粘贴。截至目前,有三版较大的改动,让我说给你听。

初具雏形 - 第一代测试框架

简单来说,第一代主要的事情就是搭建基础框架,使用parameterized实现数据驱动测试。

第一代我的目录结构是这样的:

图片

其中有4个目录和2个文件,需要解释的可能是public下的custom_tools,我将一些通用方法写在这个文件里,例如获取指定个数个字符串的random_str方法、对参数进行 md5 加密的 to_md5 方法等。

图片

图片

至于public下的tearDown_methods文件,我当时为了清理测试数据,定义了一些数据删除的方法,举个场景:接口A生成产品、接口B通过商品id编辑商品、接口C通过商品id删除商品。在这个版本中我就把接口C写到了tearDown_methods文件中,然后再在正式的测试脚本文件中定义 teardown 方法调用删除接口(此时可能就有小伙伴质疑了,你这不是脱裤子放屁么,哈哈,我刚开始的时候还认为这种写法很高端,但在不久之后我就意识到了这个问题,所以在后面的版本就改正了)。

图片

图片

正文-test_tanqiang.py的编写思路是这样的:

为了解决接口依赖的问题(例如上面举的例子:接口A生成产品、接口B通过商品id编辑商品、接口C通过商品id删除商品)我在测试文件的前部分初始化了多个全局变量 (例如 id_product = -1),然后在新增接口中,新增成功后获取产品 id,并赋值给id_product,然后在编辑和删除接口中就能使用这个值。文件结构大致如下:

图片

第一版使用parameterized装饰器做了数据驱动测试,完整的一条case如下:

图片

另外,我将不同环境和不同端的HOST写到了config文件中。

这个版本也能实现生成测试报告,并发送电子邮件的功能,想的是为日后持续集成做铺垫。

图片

第一版的成果和反思:在这种模式下,我一共写了70多个接口的case,实践证明使用Python做接口自动化测试确实比 JMeter 灵活得多,可实践后也发现如下问题:

没必要将测试数据清理的方法单独写在一个文件中,可以直接写在测试类下,因为删除接口也是接口测试的范畴。

数据驱动测试时,将测试数据罗列在测试方法上方,如果接口入参过多,那么在阅读及后期维护上很不方便 (因为得数索引位置)。

数据驱动测试时,如果其中一条 case 断言失败,也不知道具体是其中哪条数据出的问题。

测试case的执行顺序不可控。

图片

效率至上 - 第二代测试框架

根据第一代的经验和问题,重构框架,详细如下:

变动1:弃用数据驱动模式,因为做接口自动化测试的初衷就是为了做回归测试(保障原有功能不受影响),而不是通过接口自动化测试发现新的问题。再加上团队中就我一名测试,我的时间重点还是在保障功能测试上。根据以往接口受影响的经验来看,接口如果受影响更多情况会直接500,而不会是type传1接口正常,type接传2接口异常。所以在第二版中,我仅选择每个接口的正常入参,并将测试数据直接写进了测试脚本里。

图片

变动2:通过文件、类、测试方法的名称来控制用例的执行顺序。

图片

图片

变动3:移除public下的teardown_method.py文件,将数据清理接口写进test_xxx文件中的测试类下。

图片

变动4:丰富接口断言。接口自动化测试重中之重就是断言设计,所以本次改版丰富了断言类型。

图片

(有可能有的小伙伴会发出疑问:问什么都断言了响应的 code,还有必要断言响应的msg吗?我的思考是:如果你所处的团队接口开发比较规范的话其实code和msg断言其中一个就可以了,但我目前的团队并不是很规范,例如有的接口成功的响应是{‘code’:‘2000’,‘msg’:‘操作成功’},有的接口成功的响应是{‘code’:‘0’,‘msg’:‘成功’},基于此,我对code和msg都做了断言。)

变动5:接口依赖时采用 “错误先行” 编程思想。(可能有小伙伴会发出笑声,寻思为什么还有这种写法:

self.assertEqual(1, 2, ‘省份 id 获取失败,所以无法进行新建培训中心操作’),后来我也发现了这个问题,所以在下个版本中改为 “raise KeyError(‘省份 id 获取失败,所以无法进行新建培训中心操作’)”)

图片

第二版的成果和反思:在这个模式下我共集成了150个接口的自动化case。不过在实践中又发现了新的问题:如果某条 case 报错,那么报错后我并不能清楚的知道测试时的请求体的具体内容,以及响应体的具体内容。这会让我在排查以及跟开发反馈时很困难(运行完乌压压一片红,具体错在哪不是很明了)。

提升接口测试结果的可信度、持久化接口测试前中后过程中的信息 - 第三代测试框架

我加入这家公司正是团队刚刚起步的时候,所以那时迭代很快,每天都很忙,转眼入职两年了,产品预期的功能都已上线,我们公司主打的本就不是软件,IT部是职能部门,所以一旦该有的功能都有了之后也不会有太多大动作的更新(懂得都懂)。这个时候我就有时间再重新思考下当前的测试脚本了。

最近在反复的读《测试架构师修炼之道第2版》这本书(强烈推荐给大家),书中系统的教授了如何设计测试用例,从其中教授的多参数组合测试方法中得到启发,大致意思就是比如一个接口有3个必填参数(参数A(可取值:1,2,3,4,5)、参数B(0,1)、参数 C(0,1,2)),相互之间没有关联关系,据此可生成5条case:

图片

基于此,我又再次想到了数据驱动测试,这次想把测试数据源放在excel中,可能有的小伙伴就会吐槽这种excel模式的数据驱动测试,会觉得在测试前先去整理excel很麻烦。我本次的策略是,不手动在excel中数着格子填写测试数据,而是编写一个生成测试数据的方法,让其自动生成测试数据。整体思维脑图大致如下:

图片

(整体思路)

图片

(测试前编写生成测试数据的方法(需要根据每个接口编写各自的测试数据生成方法))

图片

(将测试运行过程中的 response 的相关信息写入到excel(这个方法可公用))

图片

(测试结束后,如果所有断言都通过,则将excel中对应的 case_id 置成绿色(这个方法可公用))

图片

(在testcase中调取响应的方法)

图片

(测试运行结束后,excel 中的结果)

第三版除此之外的变动主要还有:

1.将原测试脚本中的全局变量全部移到了config文件中,使得测试脚本文件更加整洁;

2.将原测试 case 中不必要的 self.去掉了,只有在断言的时候才加 (self.assertEqual()),例如之前会这么写:self.url = “XXX” self.data = {‘id’:1} ,现在改成:url = “XXX”,data = {‘id’:1},理论可度娘 “在类方法中添加 self 和不加 self 的区别”,反正我实践结果是加与不加都不影响测试结果,那自然不加(能少写就少写,~.=)。

第三版的成果和反思: 目前使用这个版本刚刚写了23个接口的case,虽然看似在写正式脚本前还要先编写一个生成测试数据的方法很麻烦,但实操发现并没有想的那么麻烦,而且这个投入产出比我认为还是很高的。也许以这个模式写的接口数量还不够多,等在沉淀沉淀一定还会发现其他新的问题。

我们的成长不就是不断的发现问题,不断地解决问题,再发现新的问题么,嘿嘿。

罗里吧嗦写了一大推,更多的是对自己在接口测试这方面从开始到现在的一个总结,就像开头说的,因为目前团队中在测试方面能相互沟通的伙伴几乎没有,所以一直都是自己摸着石头过河,走了很多弯路,现在走的路也可能不是直的,我真的真的真的真的很渴望沟通,希望各位佬儿哥佬儿姐能够不吝赐教,将发现的问题或者建议留言给我,如果能添加微信对我指点一二那简直太哇塞了(VX:GXY1162031010)。

其实重构到当前版本仍然有很多问题没有想通该怎么解决,大家帮我盘盘呗:

问题1:接口依赖怎么做数据驱动测试?

场景描述:创建产品的接口 A,调用成功之后会提取新建产品的 id,并保存为全局变量(例如:id = -1,接口 A 调用成功后置为新值,例如 id = 100),编辑产品的接口 B,在编写接口 B 生成测试数据的函数中,期望能够读取到 id 的最新值 100,实操后发现是原值-1。这个问题的原因我也知道个大概,因为运行测试前先加载所有的 ddt,然后才会运行 testcase,所以读不到在测试运行中赋予 id 的新值100。有佬儿哥指点,可以把 id = -1 写成 id = [-1],这样ddt就可以在测试运行中读到新值,我测试后确实可以,但又有佬儿哥建议接口依赖不能做数据驱动测试,所以目前还在不断试错、尝试。

问题2:针对查询接口,怎么做断言?

场景描述:新增一个产品,新增成功后拿到产品 id = 100,然后对查询产品接口 C 做断言,我目前的断言策略是 “self.assertIsNotNone(response.json()[‘data’])”(捂脸),我尝试过断言查询结果的第一条数据的 id 是否等于100,可是这种断言很不稳定,如果有多人在使用,那么列表中的第一条数据很有可能就不是你刚刚添加的数据。所以目前还没想到合适的断言方法。

问题3:在第三版的testcase中,在获取到响应后,都会固定的调用 TD.data_write() 方法,且传参内容很多,并且即使是不同的testcase,在这一步时,传入的参数都是一样的。有没有什么优化方法,可以避免每个testcase都写这么多重复的内容?

图片

如果你不想一个人野蛮生长,找不到系统的资料,问题得不到帮助,坚持几天便放弃的感受的话,可以加入我们的QQ群:746506216,大家可以一起讨论交流,里面会有各种软件测试资料和技术交流。


资源分享

下方这份完整的软件测试视频学习教程已经上传CSDN官方认证的二维码,朋友们如果需要可以自行免费领取 【保证100%免费】

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

学生HTML个人网页作业作品——湘菜美食网页设计作品(12页) 美食网站设计与实现

🎀 精彩专栏推荐👇🏻👇🏻👇🏻 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业…

图解LeetCode——1742. 盒子中小球的最大数量(难度:简单)

一、题目 你在一家生产小球的玩具厂工作,有 n 个小球,编号从 lowLimit 开始,到 highLimit 结束(包括 lowLimit 和 highLimit ,即 n highLimit - lowLimit 1)。另有无限数量的盒子,编号从 1 到…

【JavaWeb】第五章 jQuery(中篇)

🍁【JavaWeb】第五章 jQuery(上篇) 文章目录9、内容过滤选择器10、属性过滤选择器11、表单过滤器12、元素的筛选13、jQuery属性操作之html()、text()、val()方法14、jQuery属性操作之attr()和prop()9、内容过滤选择器 1)&#xf…

web大作业 静态网页 HTML+CSS+JavaScript橙色的时尚服装购物商城

常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他等网页设计题目, A…

(十)Java算法:归并排序(详细图解)

目录一、前言1.1、概念1.2、算法原理二、maven依赖三、流程解析3.1、整体流程图3.2、合并流程图四、编码实现一、前言 1.1、概念 归并排序:是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的…

Linux 安装Nginx详细图解教程

文章目录概述:安装步骤:1. 安装依赖(安装过的跳过)2. 下载nginx安装包3. 解压nginx安装包4. 安装安装nginx5. 启动nginx服务6. 配置nginx.conf7. 防火墙开端口8. 浏览器输入概述: nginx作为轻量http服务器&#xff0c…

11.22二叉树相关OJ

目录 一.每天学一个知识点 1.涉及公式 1.s.trim() 2.substring() 可以看出是满足一系列合法条件的时候,就会返回一个新的字符串. 1.思路1 栈 思路2:stringbulider 二,二叉树相关OJ题 1.检查两颗树是否相同 2.另一颗树的子树。 3.判断一颗二叉树是否是平衡二叉树 1.时…

大数据培训课程GroupingComparator分组案例实操

GroupingComparator分组案例实操 1.需求 有如下订单数据 表4-2 订单数据 现在需要求出每一个订单中最贵的商品。 (1)输入数据 (2)期望输出数据 1 222.8 2 722.4 3 232.8 2.需求…

python数学建模--时间序列模型--指数平滑

目录时间序列指数平滑一次指数平滑预测示例二次指数平滑预测示例三次指数平滑本博客参考:《python数学实验与建模 》 时间序列 时间序列数据是按照时间顺序排列的、随着时间变化且相互关联的数据序列,这类数据往往反映了某一事物、现象等随时间的变化状…

升级光伏供应链体系,供应商系统规范供应商管理,促进企业与供应商高效协同

作为过去十年我国发展最快的可再生能源,截止到2020年光伏累计装机量达到253GW,过去10年复合增长率达到20%以上,新增光伏装机48.2GW,同比增长60%。全球可再生能源署预计2050年光伏累计装机规模将达8519GW,成为最主流的电…

【MySQL】 B+ 树存储的原理

1. B 树 和 B 树 B Tree 模拟生成工具:https://www.cs.usfca.edu/~galles/visualization/BTree.html BTree 模拟生成工具: https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html B 树 —— 1970年,R.Bayer和E.mccreight提出了一种…

[附源码]java毕业设计学生量化考核管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

LIN休眠唤醒及测试心得

上期LIN测试小课堂,我们分享了LIN总线帧结构及各场干扰,如何测试样件是否不响应错误的帧结构。 这次我们的介绍主题是LIN休眠唤醒,一起看看标准和差异性,开发和测试的关系,实际的案例分享也来了。 一、LIN控制器休眠…

编译原理—语义分析、语法制导翻译、翻译模式、中间代码生成

编译原理—语义分析、语法制导翻译、翻译模式、中间代码生成语法制导翻译语法制导定义(属性文法)翻译模式后缀式图示表示法构建表达式的语法树中间代码的种类三地址码四地址码对比举例中间代码产生的场景说明语句的翻译举例嵌套说明语句的翻译方案相关定义举例过程嵌套声明记录…

BDP FL-PEG5-炔丙基,2093197-93-2,BDP FL-PEG5-propargyl是一种 BDP FL 接头

BDP FL-PEG5-propargyl ​中英文名: CAS号:2093197-93-2| 英文名:BDP FL-PEG5-propargyl |中文名:BDP FL-五聚乙二醇-炔基, BDP FL-PEG5-炔丙基BDP FL-PEG5-propargyl ​物理参数: CASNumber:20…

微信小程序基础学习(5):使用 npm包、全局数据共享、分包

1. 使用 npm包 1.1 小程序对 npm 的支持与限制 目前,小程序中已经支持使用 npm 安装第三方包,从而来提高小程序的开发效率。但是,在小程序中使用 npm 包有如下 3 个限制: 不支持依赖于 Node.js 内置库的包。不支持依赖于浏览器…

查看进程信息(ps、top) + 操作后台进程(jobs、bg、fg)

目录 1、查看进程信息 (1) 查看进程快照 —— ps (2) 查看进程的动态信息 —— top (3) 查看进程的详细信息 —— /proc 2、操作后台进程 (1) 将进程转为后台 (2) 将后台进程转为前台运行 fg (3) 查看后台进程 jobs 1、查看进程信息 (1) 查看进程快照 —— ps 所谓…

Word控件Spire.Doc 【图像形状】教程(3) :在 C#/VB.NET 中的指定位置插入图像

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下,轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具,专注于创建、编辑、转…

【无标题】接口测试遇到的典型bug纪录

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

Java#22(内部类)

目录 一.内部类 1.什么是内部类? 2.什么时候用? 3.特点 二.成员内部类,静态内部类,局部内部类(稍微了解即可) 1.获取成员内部类对象的两种方式? 2.外部类成员变量和内部类成员变量重名时,在内部类如何访问? 2.静态内部类 3.局部内部类 三. 匿名内部类…