gitbook/接口测试入门课/docs/193688.md

189 lines
19 KiB
Markdown
Raw Permalink Normal View History

2022-09-03 22:05:03 +08:00
# 02 | 方法论:没有任何文档,怎么才能快速了解接口的信息?
你好,我是陈磊。
我相信在学习完上一节课后你已经明白了接口测试是在测什么我们为什么需要做接口测试。那么当你面对一个接口测试任务的时候你知道该如何开始吗其实任何事情从0到1都是一个门槛你只要跨过这个门槛后面就会一马平川。今天我就来告诉你如何开始接口测试让你面对一个项目不再束手无策也不再面露难色。
说起接口测试,我想你并不陌生。作为一名测试工程师,尤其是做了多年业务测试的测试工程师,在开始接触接口测试时,无论开发工程师是否提供了接口文档,我相信你都会对下面几种场景似曾相识:
1. 开发工程师提交测试的项目附带着一个几十页的Word文档里面是一行一行的访问地址和路由面对这样的Word文档不知道如何开始验证
2. 开发工程师在即时通讯工具上,甩给你有好几页的这么一个传输消息,里面有各种嵌套的参数,你不知道这些参数都是干什么用的;
3. 开发工程师口头告诉你需要测试的接口地址,然后就什么都没再多说,你问了他几句话后,他就借口说自己忙,不再理你,而你看到那个又长、又复杂的地址,束手无策。
难道,面对这些状况,测试工程师就没办法自己分析接口,完成测试吗?我现在告诉你,当然不是。
接下来,我就带你一起看看,一个理想的提测项目是什么样的,在实际工作中,绝大部分的提测项目又是什么样的,然后我们一起看看,如何一步一步解决一个不理想的提测项目。
## 一个理想的提测项目
一个理想的提测项目,在提测的过程中应该既包含前期参与的产品需求、原型设计,这些是由产品经理来提供的;也包含后端接口文档、代码单元测试脚本,这些是由开发工程师提供来的。它们都是你开展测试的必要输入内容,具体有这些作用:
* 产品需求。它描述了系统的业务逻辑,通过这个文档,你才能知道怎么来设计测试用例;
* 原型设计。它会更加直观地告诉你系统的使用逻辑,这对测试用例的设计、对系统的前期认知都是有辅助作用的。
* 接口文档。它详细地描述了后端接口的访问方式和参数说明,使用这个输入项才能开展接口测试用例的设计、测试脚本的准备和测试数据的构建。
* 单元测试脚本。它是保障提测质量的必要环节,是研发工程师自测的一个有效手段,可以保障提测项目的提测质量。
这些内容不限制SUTSystem Under Test被测系统的类型SUT既可以是一个手机App也可以是一个Web服务甚至还可以是一个微服务接口。
所以,对于接口测试阶段来说,一个非常理想的接口测试,就是从完美的接口文档开始的。开发工程师在设计和开发接口的过程中,就在不断维护和更新接口文档,这其中包含了每一个接口的访问方式、访问路由、输入参数含义、返回参数含义,以及一个完整的例子。
这种接口文档可能是以Word文档形式存在也有可能是以类似Swagger这种工具形式存在。说到Swagger它是我推荐给你的一个接口文档的存在形式是一个从代码生成的、以Web服务形式存在的接口文档它可以伴随代码的变更同步变化这就减少了很多开发工程师和测试工程师之间的沟通成本。
由Swagger生成的接口文档的例子如下图所示从图中你可以看到它对接口的访问方式、访问路由、参数都有着详细的描述。
![](https://static001.geekbang.org/resource/image/de/64/de22757455c405cd60f5490801c8ef64.jpg)
这样,当你拿到接口文档时,就可以快速使用各种工具或者代码来完成你的单个接口测试任务了。与此同时,你还可以通过一些参数设计、参数上下文传递,来完成接口的流程测试。
## 理想的情况很难发生
上面我说的是很理想的情况,现实却往往并不总如人意,我相信你也肯定遇见过下面这些情况:
* 根据产品经理的一句话需求,开发工程师便开始任意发挥,“所见系统即需求”的情况普遍存在,这就更别说后续的单元测试和接口文档了;
* 开发工程师从来不写单元测试脚本,提测项目质量无法保障,接口文档更无从谈起,你不知道如何开始完成接口测试;
* 你在拿到提测项目后从部署测试环境到开始测试一直都是摸黑前进由于接口测试没有充分的输入条件只能从UI层开始测试结果导致交付质量大打折扣。
就像墨菲定律说的那样:可能发生的事情必将会发生。所以,上面我列举的接口测试难以推行的一些常见情况,都是你在工作中会碰见的问题。
那么,如果一个项目没有接口文档,我们就无法开始接口测试了吗?当然不是。
测试工程师的工作本质上是一个由表及里的工作,如果你还是每次工作都处在和终端用户使用行为几乎一致的流程上,那么只能说明你还不算一名合格的测试工程师。
其实,无论开发工程师给我们的输入项是否包含了接口文档,我们都可以通过一些技术手段和工作方法,完成接口测试必要的输入项接口文档的创建。
那么这样的工作如何开始呢?下面我就来和你一起完成这样一项任务,教你如何开始第一个接口测试。
## 开始第一个接口测试
在拿到一个SUT环境的时候你首先就要进行接口测试这是因为单元测试不是由测试工程师来完成的而是由开发工程师编写、并由持续集成系统自动完成执行的。
如果开发工程师没有给我们任何有价值的文档,那么要开始接口测试,你可以通过工具辅助、分析问题、询问解惑这三个步骤来完成。
![](https://static001.geekbang.org/resource/image/52/0c/52483652c86dc2ce7f3459a1d773c30c.jpg)
具体的工作模式如上图所示:
1. 借助一些工具的辅助来完成接口分析;
2. 通过工具截获一些接口信息;
3. 通过分析接口的访问方式、参数等信息整理出一些问题,和研发工程师沟通这些问题,将一些不知道的参数含义、参数取值范围等问题问清楚。
通过这三步的循环你就可以完成对SUT系统接口信息的完善和维护最终得到一份完整的、接口测试需要的输入—接口文档。
下面我会结合一个案例,带你看看这三步具体该如何进行。
### 工具辅助
当你第一次拿到一个被测项目无论它是一个App服务还是一个Web服务你都可以通过一些HTTP代理完成接口分析这里我推荐你使用Fiddler这款工具。
> **注意:**
> Fiddler既支持Windows操作系统也支持MacOS操作系统但是在MacOs上的版本并不好用这是因为Fiddler使用了.Net开发。如果你是一个MacOS深度用户那么我推荐给你两款工具一款是Charles另外一款是mitmproxy。其中Charles是商业软件mitmproxy是开源软件但是Charles使用起来更简单mitmproxy的使用则稍微复杂一些你可以依据自己的喜好来选择。
简单来说Fiddler[在这里下载](https://www.telerik.com/fiddler)是一个HTTP的调试代理也就是一个HTTP协议的抓包工具运行时会在本地建立一个代理服务默认地址为127.0.0.1:8888。当浏览器和被访问的服务之间发生交互的时候Request请求和Response响应都会经由Fiddler代理这样就可以截获下全部的访问信息流了。
在接下来的内容中我会带你使用Fiddler来完成接口的分析任务**但是我并不打算手把手的把Fiddler这个工具的使用细节讲述给你因为除了Fiddler其实还有很多工具可以完成对应的任务每一种工具又都有其具体的使用方法这里我真正想告诉你的是通过具体的方法来解决问题的思维。**
### 分析问题
在解决问题前,我们首先要分析问题,这也是我们开始接口测试的第二步。
下面我们一起来使用Fiddler分析一下极客时间Web端首页极客时间Web端首页地址https://time.geekbang.org
首先打开Fiddler然后启动浏览器访问极客时间Web端首页我们可以看到Fiddler截获了很多消息找到刚刚输入的https://time.geekbang.org如下图所示在右侧上方Inspectors的标签页下你就可以看到Request请求的内容和Response请求的内容了。
![](https://static001.geekbang.org/resource/image/59/bd/599426c3540b73b0bb673dda2ae0ebbd.jpg)
为方便你查看我将Request的消息体复制出来如下
```
POST https://time.geekbang.org/serv/v1/column/topList HTTP/1.1
Host: time.geekbang.org
Connection: keep-alive
Content-Length: 0
Accept: application/json, text/plain, /
Origin: https://time.geekbang.org
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Referer: https://time.geekbang.org/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _ga=GA1.2.2063652238.1573441551; _gid=GA1.2.1275017383.1573441551; Hm_lvt_022f847c4e3acd44d4a2481d9187f1e6=1573441551; GRID=b0a2570-01c8b13-90b002b-568dc07; MEIQIA_TRACK_ID=1TS7HZW4C6OWaPSu5VGIj7uN4pM; MEIQIA_VISIT_ID=1TS7HWSYajeZyS29IqNNyvW9cyY; SERVERID=1fa1f330efedec1559b3abbcb6e30f50|1573441580|1573441549; _gat=1; Hm_lpvt_022f847c4e3acd44d4a2481d9187f1e6=1573441790
```
从这段消息体中我们可以获知它的访问方式是POST访问的URI是“[https://time.geekbang.org/serv/v1/column/topList](https://time.geekbang.org/serv/v1/column/topList) ”。这里面的具体属性内容,你可以自行查看,但是,我希望你重点关注如下这几个属性:
* HOST它表示指定访问的服务器域名
* Connection的值为keep-alive这表示需要持久连接
* Accept它表示客户端可以接受的内容类型为application/json, text/plain, _/_
* User-Agent它说明请求是从什么浏览器发出去的
* Sec-Fetch-Site和Sec-Fetch-Mode它们是JS中对跨域的一些设置
* Accept-Encoding设置为gzip、deflate、br这表示可以支持的Web服务器返回内容压缩编码类型
* Accept-Language它表示接受的语言。
这其中的Cookie的内容是你需要特别非常关心的因为Cookie中传递的参数很多都是用来确认用户身份、鉴定角色权限等需要的参数。这样通过上面的分析你就可以自己绘制如下的表格这里我也给出了一张表格。
![](https://static001.geekbang.org/resource/image/08/68/08453bfd82584f4fce9c1c16140d0468.jpg)
在这个表格中被标注为白色背景的部分是这次访问的基本信息被标注为黄色背景的部分是访问的头信息同时也是我们已知的内容被标注为红色背景的部分就是Cookie信息是我们未知的内容。同时你可以看到本次消息访问的body是空的是没有内容的。
接下来我们再看看这个请求的Response信息由于返回的消息比较长我在这里就不贴出来了但是通过下面这个图你可以看出这次返回的主体是一个很长的JSON这里面包含了各个专栏或者课程的信息。
![](https://static001.geekbang.org/resource/image/6b/76/6b177a4d543c1799875ca3417f9ada76.jpg)
这些返回值包含了很多参数,你也需要关注这些参数,因为很多时候,一个接口的返回值会是另外一个接口的入参,也就是我常说的串联业务逻辑上下文的参数。
现在在你绘制的接口信息表中还有一些未知的Cookies内容就如我前面说的Cookie内容是完成接口测试必须要模拟并传递的一些信息因此我们必须要尽可能完善它使它成为接口测试的必要输入条件之一。
这样,拿着这张接口信息表,我们就进入了第三步,询问解惑。
### 询问解惑
对于本次访问的Cookies的参数从参数语义上来说我们无法知道这些参数是用来干什么的他又起到了什么作用作为测试人员我们也无法只靠自己知道每一项具体的含义、表示的内容以及参数的作用。
因此,我们需要拿着上面的那张表格,找到对应的开发工程师,去问清楚表格中标红部分的参数。
针对每一个参数,你都要从下面的几点详细询问,并保证你已经真的理解了这些内容。那么,都询问些什么呢?我认为主要有三点。
1. **参数的含义以及来源**。你要搞清楚每一个参数的含义也就是这个参数对应的实际自然语言的名字通过记录每一个参数的中文语义也会让更你容易记住这个函数是干什么的。同时你也要知道这个参数的赋值是从哪里来的是从其他页面的返回值中得到的还是JS生成的如果是其他页面或者接口返回的那么是哪一个接口返回的哪个字段这样当你开始做接口测试的时候你就知道去哪里拿到这个参数的赋值了。如果是另一个接口的返回字段那么你还需要维护一份返回该参数接口的接口信息文档以便于自己下一次创建对应的参数如果不可以创建那么你就要知道这个参数的生成规则也要知道如何手动构造它。
2. **参数的作用域**。参数的作用域指的是这个参数在这个接口中是做什么用的,它在哪一个访问周期里是一直存在的,它是否导致了业务逻辑分支等。比如说,这个参数是用来验证用户权限吗?它的验证算法是什么?之所以要搞清楚这些内容,是为了你在做接口测试的时候,可以设计更小的参数组合来覆盖更多的业务逻辑,这是测试用例去除冗余的一个很好的方法。
3. **返回值的含义**。针对上面一大串的返回JSON你要搞清楚在返回值中每一个JSON的Key所对应的含义这样当你需要和这个接口产生交互的时候就可以快速地拿到对应参数的含义完成业务逻辑上下文的参数串联了。
总地来说Request的全部参数和Response的全部参数对于接口测试来说都是必要的输入项因此我们有必要花费很多精力完善并且留存它们。
OK到现在你已经借助工具、通过分析问题明确了未知参数也通过询问解决了未知参数的中文含义、作用域以及对应返回参数的中文含义现在即使面对没有接口文档的提测项目你也能收集明确的、足够的信息了。
那么接下来,你就可以利用这些信息,完成业务逻辑的接口测试了。
## 多个接口串行分析
在质量保障过程中测试的主要任务是保障SUT的业务逻辑正确性而单一接口的测试却很难完成一个业务逻辑所以在大部分的测试场景中我们都需要串行多个接口才能完成一个完整的业务逻辑。
然而,即使我们按照上述三个步骤完成了全部单个接口的分析,也并不能马上开始进行接口测试。这是因为,一个测试的业务逻辑是由多个接口的串行完成的,而多个接口的串行逻辑是由业务逻辑规定的,因此,多个接口之间并不是随意组合的,而是按照业务逻辑、通过数据传递来完成的。
这其实就和拼图游戏一样,我们有一堆拼图碎片,很多拼图碎片都可以连接到一起,并不会有明显的不适合,但是,依据拼图的最终图形,这些拼图碎片就是不能放到一起。你要想把拼图完成,就不仅要考虑各个拼图碎片是不是可以链接到一起,还要考虑这些碎片放到一起后是不是对原来图形的正确拼接。
那么,你前面整理好的、各个单一接口的信息表,就是拼图游戏里的一个拼图碎片,业务逻辑就是拼图组成的最终图形,而其中的参数,就是拼图碎片的缺口和每一个碎片上的图形。
所以,要想使用接口测试完成业务逻辑,你就要制作一个流程中所有接口的接口信息表,同时,还要理清每一个流程的数据流程,数据流程驱动了业务流处理,这样,才能开始业务逻辑的接口测试。
关于怎么完成一个业务逻辑的接口测试,我会在下一节课中详细的解释给你。
## 总结
好了,今天的内容就到这里了,不知道你是不是已经掌握了分析一个接口并整理接口信息表的方法呢?现在我来总结一下。
在今天的课程中,我带你一起分析了一个理想的提测项目都包含哪些要素,但是,这种乌托邦式的提测项目在现实中却很难遇见。所以,我给你推荐了“三步走”的方法,你可以通过工具辅助、分析问题和询问解惑这三步来建立接口信息表,建立和维护自己的接口知识库。我也通过拼图游戏的例子,告诉你接口测试的业务逻辑验证思路。
随着被测系统的不断迭代,当你不断地按照这个步骤积累起自己的接口知识库时,你就会拥有自己负责的业务线的业务知识积累,变成这条被测业务线的业务专家;同时你也会拥有每一个接口的输入和输出全部参数、每一个业务逻辑的数据流、每一个驱动业务分支逻辑的参数条件,你也会成为接口测试的技术专家,在你自己的工作中变成一个不可或缺的质量保障者。
在一个团队中,有很多时候,测试工程师和开发工程师之间就是一个矛盾的共同体,既相互依存又不可分割,在团队中缺一不可,要想摆脱“测试非技术岗位”的帽子,就需要测试人员有自己的技术功底和技术素养。
无论你在工作中,遇到的是能很好相互支持的开发工程师,还是不好合作的开发工程师,你都要保持自己的技术能力,尽最大努力完成自己能够完成的所有事情,只有这样,你才能提高自己在团队中的话语权。
## 思考题
最后我想请你来思考一下你能用本节课讲述的Fiddler还有接口测试分析方法完成一个你自己项目的老旧接口的分析吗
我是陈磊,欢迎你在留言区留言分享你的观点,如果这篇文章让你有新的启发,也欢迎你把文章分享给你的朋友,我们一起沟通探讨。