关于接口测试的一点小小的感悟

接口测试的目的

这个算是老生常谈了,但我觉得只要聊到接口这个还是绕不过的,没有目标就没有评判标准,所以测试的目的还是很重要的。

先搬运一下维基百科上的英文解释(中文没找到,百度的就算了。。。):

API testing is a type of software testing that involves testing application programming interfaces (APIs) directly and as part of integration testing to determine if they meet expectations for functionality, reliability, performance, and security.[1] Since APIs lack a GUI, API testing is performed at the message layer.[2] API testing is now considered critical for automating testing because APIs now serve as the primary interface to application logic and because GUI tests are difficult to maintain with the short release cycles and frequent changes commonly used with Agile software development and DevOps).[3][4]

翻译过来就是:

API 测试是一种作为集成测试的一部分,通过直接控制被测应用的接口(API)来确定是否在功能、可靠性、性能和安全方面达到预期的软件测试活动。[1]由于 API 都没有 GUI 界面,API 测试都是在通讯层进行的。[2]现在 API 测试在自动化测试中有着很重要的地位,因为 API 一般是应用逻辑的主要接口,同时 GUI 测试在敏捷开发和 DevOps 的快速迭代和频繁变更中很难维护。[3][4]

然后我目前在工作中 Leader 对我的预期:
发现尽可能多的问题。先说下背景,他是 app 端的主程,他对我做接口测试的期待是尽早发现接口的问题,减少他们 app 和服务端联调是发现的问题。他举了个例子,例如服务器返回一个 {"width":30, "url":"http://xxx/a.jpg"} ,那么有可能存在这个图片的实际宽度和 width 字段不一致。

和大东等曾经做过 API 测试的人的交流:
覆盖业务,包括业务正常/异常的情况

  • 我一开始的理解:

发现问题,恩。那就是把文档里说的必须字段缺了试试,只有必须字段试试,必须字段用非法值试试。可选字段缺了试试,可选字段非法值试试。
结果就是:一个接口至少6个用例,甚至更多。而且很多时候不一定测得到业务(如接口只返回成功失败,但有可能实际上失败了但返回的是成功,需要调用其他接口验证)

  • 目前的理解(估计还是有点走偏):

结合业务设计用例。如有翻页参数,那就试试默认值、有效值、最后一页、最后一页+1、无效值。针对各个参数和业务场景去设计用例。

软件测试交流群:747981058

接口测试的实现

在这一点上我走了两条路:Jmeter 和纯 Java 代码。现在看来,两条都不是好路,所以就不分享了。这里主要说下 Testerhome 上最近出现的一些接口测试工具方面的帖子,简单汇总一下他们的实现方式:

序号 文章 主要采用技术 写用例的形式 预测写用例的速度 是否支持灵活的、编程语言级别的断言
1 接口自动化测试实践的记录 By simonpatrick 核心基于 Spring RestTemplate ,主要有三个部分:Service 的描述,测试数据,客户端调用。由于各接口代码比较统一,能实现代码自动生成 Java 编写接口最基本的数据获取(testng的DataProvider)和收发请求代码,excel存储测试数据和预期结果 快(接口描述及用例的 Java 代码部分可以自动生成) 不支持,估计只支持字段级别的数据校验
2 雪球的 HttpApi 接口测试框架设计 By seveniruby 采用 scala 编写,灵感来自百度内部的 SuperTest 录制成 har + api/dsl/csv 格式传递参数 快(基于录制,因此录制完毕后只需要修改参数和断言即可,不用花时间去写结构方面的东西) 支持 scala 的断言
3 [分享] 自动化测试与持续集成方案--Jmeter 测试接口及性能 By snake Jmeter+Jenkins Jmeter的图形化界面(支持录制) 较快(需要修改的地方略多) 支持(Assertion 通过插件支持 BeanShell、Javascript 等语言进行断言)
4 java+selenium+Web API 自动化测试框架分享 By xushizhao GUI使用了jquery. 后端使用java做了公用方法进行解析,基于数据驱动 有通过json串解析输出结构的功能。GUI 上将收集的输入、输出数据以树型结构展现,通过简单的勾选来完成测试用例的输入参数及预期输出结构进行关联生成测试用例。 较快(对于接口基本信息采集有一定工作量) 不支持(支持规则验证、输入参数集合绑定等)
5 API 自动化测试框架分享 By testly Jenkins + Svn + Maven+TestNG+ReportNG+(HttpClien+URLConnection) excel 表格 不支持(支持关键字段检查)
6 WeTest 接口自动化测试框架 By neven7 Junit + HttpClient,定位更像 TestNG 这样的执行层框架 Java 代码 较慢(接口数据、接口断言等都需要自己写到用例中) 支持(本身就是 Java 语言)
7 我目前使用的方式(乱入。。。) TestNG + ReportNG + OKHttpClient + Json 处理库(gson, jsonpath) Java 代码 这不是预测,一天20条已是极限,平均每条用例需要写30行以上的代码 支持(本身就是 Java 语言)
8 我之前使用的方式:Jmeter Jmeter Jmeter 的图形化界面(支持录制) 一般(好吧,我还驾驭不了,或者说我的需求对 Jmeter 要求太高了,基本所有断言都要自己写 Javascript 来做) 支持(可通过 Javascript 语言进行断言)

到目前为止的做过的接口测试的总结

怎么说呢,我觉得我现在做的虽然也是接口测试,但我设计的用例更多的是具体功能。例如发表朋友圈,我会调用上传接口(顺带检查上传的文件 md5 对不对,顺序对不对,相关属性字段对不对),发圈子接口(基本就检查返回值就够了,但要有不同类型的文字,包括特殊符号、长度等),查看圈子接口(图片 md5、顺序、相关属性对不对、发布人对不对、回复和点赞方面的数据对不对)。因为是三个独立的接口,所以每个接口都需要有一定的封装方法(发信息的、获取返回值里指定字段的,等)。每个封装方法平均10行代码左右,一个用例用3个接口基本就需要 3x10+10(一些说明和不好封装的部分)行代码。一个功能大概要覆盖10个用例,所以就需要10x40行代码,就是400行代码。除去一些可以共用的代码,基本需要300行代码左右(某些复杂功能会更多)。

PS:通过 git 统计了一下我每天的代码量,大概在1000左右,但用例数还是每天15个左右。

可以看出,我的速度主要是慢在了代码量太大,时间都用在打代码上了,而且代码调试起来又会花一定的时间,所以效率自然低。所以如果优化写用例的方式,就算吐血也写不快了。接下来得总结一下那些地方可以抽取出来,用录制或者自动生成的方法来完成,把写用例精简成填表格或者纯填数据。

Updated 2015.11.30

今天和 Monkey 以及公司另一位有做过 api 测试的同事交流了一下,发现了一个最根本的问题: 我的用例设计有问题

这个讲概念比较难说清楚,还是以上面提到的发表朋友圈作为例子。

假设我要验证发表朋友圈的 接口,它的工作流程如下:

  • 上传图片,服务器返回这些图片的 url
  • 发表朋友圈,包含朋友圈文字内容和各个图片 url 两个主要字段。服务器只会返回是否成功以及这条朋友圈的 id

我设计的正常发朋友圈的用例如下:

  • 用上传图片接口上传图片,验证图片是否上传成功,各 url 对应文件的 md5 是否和我本地上传的图片的 md5 吻合。
  • 用发本地圈接口发本地圈,其中图片 url 来自第一步的返回值
  • 用查看本地圈接口查看发出的本地圈,检查它的内容、图片是否正确。

咋看之下好像没啥问题(相信做过 api 测试的童鞋已经看出问题了),但其实这个用例本身存在一个严重的问题: 接口成为了手段,验证点其实是功能。

我交流后得到的 api 测试用例主要应该有两类:

  1. 单一接口测试。调用一个接口就是一个用例
  2. 多接口的业务测试。会调用多个接口,且接口之间可能存在数据传递。

api 测试最简单,并且每个接口都应该至少有一个的用例应该就是使用 默认参数调用 单个接口。重点在这里:单个。像我上面这样的用例已经不是验证发朋友圈的接口了,而是验证 发朋友圈的功能

那么发朋友圈的接口应该有什么用例呢?我按照现在的测试接口的思路重新想了一下,主要有这几个:

  1. 有图片、有文字,预期返回发布成功
  2. 无图片,有文字,预期返回发布成功
  3. 有图片,无文字,预期返回发布成功
  4. 无图片,无文字,预期返回发布失败
  5. 有图片、有文子,预期返回发布成功,同时数据库中的记录符合预期

每一个用例测试一个点,发布成功这个返回值是否正确由一个单独的用例来覆盖就足够了。

用例确定了,那么可以看出接口测试其实有很多可以重用的点。接口测试的本质是通过测试参数的排列组合验证返回值/数据库变更是否符合预期,从而确定接口相关代码是否正确。从业务角度考虑的意思是这些排列组合不是随便想出来,而是业务中有可能出现的排列组合。

这也是为什么不少接口测试用例采用 excel 表格来编写,因为参数的排列组合用表格呈现是最简单快捷的。

还有一个例子说明用例越简练越好。

例如列表接口有个翻页的功能。它有一个入参:lastTopicId ,返回值里有一个 isMore 的字段。lastTopicId 表示从哪个 topic 开始显示, isMore 表示是否存在下一页(1为有,0为无)。

针对这个接口的其中一个用例,需要验证 isMore 字段在最后一页时是否为0。我一开始的思路是像功能那样,不断翻页,直到达到一个很大的页数或者到达 isMore 为 0 的情况。由于页数不确定,因此就算这个很大的页数设得非常大也没有十足的把握绝对不会超出这个页数。所以思路本身有问题。

和 Monkey 和我的同事交流后,他指出正确的思路应该是:

  1. 通过一个可信的途径(从服务器数据库直接计算,或者有一个端口告诉你最有一页的 lastTopicId 是什么),用一个步骤知道怎么一次性去到最后一页。
  2. 直接去到最后一页
  3. 验证 isMore 参数值

有些东西开发可以很方便地给到我们,那么我们没有必要那么艰难地自己去计算出来,而是直接让开发增加一个接口让我们能直接获取到数据就好。让接口测试做得更好,开发的协助是分不开的。

做好接口测试并不像之前想象得那么简单,但也没有刚开始的时候做得那么艰难。不管怎样,既然开始了,那就要想办法把它做好。



跟大家推荐一个学习资料分享群:747981058,里面大牛已经为我们整理好了许多的学习资料,有自动化,接口,性能等等的学习资料!

人生是一个逆水行舟的过程,不进则退,咱们一起加油吧!

 

原文地址:https://www.cnblogs.com/nanaheidebk/p/10142938.html

时间: 2024-10-11 12:58:18

关于接口测试的一点小小的感悟的相关文章

关于Node.js, Jade一点小小的介绍。

本文出自:http://blog.csdn.net/svitter node.js大家知道的可能比较多,但是jade大家可能就不知道了..GFW封杀掉google以后,今天在百度上找了好久也没有找到--哎,仍需前进. 肯定有在github上获取一些框架的小白和我一样,看了到了json,jade,less这些莫名奇妙的东西然后怅然不知所云. jade可以用来生成html文件,写法要简单很多.具体见:http://jade-lang.com/ 那么jade是什么呢?jade就是node 的一个框架,

AngularJS』一点小小的理解

『AngularJS』一点小小的理解 AngularJS 是一个前端的以Javascript为主的MVC框架.与AngularJS相类似的还有EmberJS. 随着时代在进步,各种各样的开发理念与开发框架不断的提出与发展,而就目前来说,除了游戏.IM(类似QQ).Office这类软件之外,新出的软件应用开始出现两个方向,一个是以Web为主的Web APP,一个是以移动端为主的移动APP.且,现有也有一种声音认为Web APP早晚会取代移动端原生APP,从而一统计算机软件的应用方式.暂且不论这种说

C# 异步工具类 及一点小小的重构经验

2015年新年第一篇随笔, 祝福虽然有些晚,但诚意还在:新年快乐. 今天主要是想分享一异步工具类,在C/S架构中.先进行网络资源异步访问,然后将回调函数 Invoke到UI线程中进行UI处理. 这样的场景是及其常见的,因此特意封装了一工具类,用以简化操作. /// <summary> /// 异步工具类 /// </summary> public class TaskTools { /// <summary> /// 是否 在执行回调函数之前修改Running状态 //

一点小感悟关于df lsblk fdisk命令关于三种存储

物理块与文件系统之间的关系图: 映射关系:扇区→物理块→逻辑块→文件系统 dfisk:物理块  lsblk:逻辑块  df:文件系统 分布式存储的应用场景根据其存储接口,即提供的访问接口,现在流行分为三种: tip:所谓数据存储的接口,就是数据传到哪里你就得接走去存,接走后,剩下的工作就是你做,由你落盘,至于从谁手里接,得看你打交道的对象的支撑.对象存储: 也就是通常意义的键值存储,其接口就是简单的GET.PUT.DEL和其他扩展,如七牛.又拍.Swift.S3.我认为是从应用层把数据接走,数据

《超凡蜘蛛侠2》的一点产品感悟

今天跟最好的朋友DOZ还有他媳妇我们仨人一起去看3D原声<超凡蜘蛛侠2>.先后有一些产品的感悟,待我细细讲来. 在观看前,D先生一直给我说<超2>有什么好看的,就是在炒冷饭.但是在结束的时候,我问他怎么样,他说:"还不错啊,毕竟是美国大片,投资了那么多钱." 他的回答就是产品体验. 对产品来讲:产品首先需要通过各种宣传方式让大家知道它--其次,产品要有真功夫,确实能够解决实际存在的问题,且用户体验要在资源可以调配的最大程度内做到最好--用产品的使用价值+优秀的体

关于Quartz.NET作业调度框架的一点小小的封装,实现伪AOP写LOG功能

Quartz.NET是一个非常强大的作业调度框架,适用于各种定时执行的业务处理等,类似于WINDOWS自带的任务计划程序,其中运用Cron表达式来实现各种定时触发条件是我认为最为惊喜的地方. Quartz.NET主要用到下面几个类: IScheduler --调度器 IJobDetail --作业任务 ITrigger --触发器 如果我们自己采用Timer来写类似的定时执行任务程序的话,相应的我们应该有:(以下均为设想,目的是让大家搞清楚Quartz.NET上面三个接口的关系) Schedul

关于tasklet的一点小小的解释

大概有一些同学对tasklet的串行化还有点困惑,其实在单处理器上最好理解,所以本帖主要讨论多处理器上tasklet如何实现串行化:同一个tasklet对象同一时刻只能在一个处理器上运行. 在 驱动程序中,tasklet是作为一种softirq形式出现的,所以对tasklet对象的提交一般发生在中断处理例程ISR中.一般一个 tasklet用来对同一种中断类型进行后续的处理,所以完全不必要通过动态生成tasklet对象的方式在每次中断到来时重新生成一个tasklet对 象来做后半段的处理.事实上

关于抽象类和接口的一点小小的认知

抽象类可以继承具体的类 抽象类在实现接口的时候,可以不用实现接口的方法.但是子类一定要实现.因为子类不具有抽象方法,而抽象类具有抽象方法.因此,可以不用实现. 抽象类除了不能new对象,其他的和具体的类没啥太大的区别. 接口的话,只能在接口中定义抽象方法和静态常量. 抽象类是一个模板,继承的子类一定要实现它的抽象方法.当然也可以子类也是抽象类,那就可以不用实现了,只需要再声明为抽象方法就可以了. 接口给人的感觉是一种可插拔的感觉.既然是可插拔的,那么我们就可以用到很多地方了啊(当我们需要通用时)

ef core数据迁移的一点小感悟

ef core在针对mysql数据迁移的时候,有些时候没法迁移...有两种情况没法迁移,一种是因为efcore的bug问题导致没法迁移,这个在github上有个问题集,另外一种是对数据表进行较大幅度的变更,导致外键导航之类的变更较多,无法正常迁移,并且涉及到该表的迁移有多条. 然后我就自己琢磨,在不删除所有迁移记录的情况下怎么顺利把数据表更改掉,然后摸索了一阵,确实成功了,步骤如下. 1.先把表备份后,删除这个表.2. 在migration记录表中,涉及到该表的迁移全部删除.3. 删除迁移记录中