极客时间已完结课程限时免费阅读

22 | 从0到1:API测试怎么做?常用API测试工具简介

22 | 从0到1:API测试怎么做?常用API测试工具简介-极客时间

22 | 从0到1:API测试怎么做?常用API测试工具简介

讲述:茹炳晟

时长16:32大小7.57M

你好,我是茹炳晟,我今天分享的主题是“从 0 到 1:API 测试怎么做?常用 API 测试工具简介”。
在第 11 篇文章《互联网产品的测试策略应该如何设计?》中,我介绍过当今互联网产品的测试策略往往会采用菱形结构,即重量级 API 测试,轻量级 GUI 测试,轻量级单元测试,由此可见 API 测试在现今测试中的重要性不言而喻。
这篇文章是 API 自动化测试系列的第一篇文章,我会先为你打好 API 测试的基础。所以,我会先从 0 到 1 设计一个 API 测试用例,通过这个测试用例,你可以体会到最基本的 API 测试是如何进行的,并介绍几款常用的 API 测试工具。

API 测试的基本步骤

通常来讲,无论采用什么 API 测试工具,API 测试的基本步骤主要包括以下三大步骤:
准备测试数据(这是可选步骤,不一定所有 API 测试都需要这一步);
通过 API 测试工具,发起对被测 API 的 request;
验证返回结果的 response。
对 API 的测试往往是使用 API 测试工具,比如常见的命令行工具 cURL、图形界面工具 Postman 或者 SoapUI、API 性能测试的 JMeter 等。
为了让你更好地理解 API 测试具体是怎么做的,并掌握常见 API 测试工具的使用,我会以基于主流 Spring Boot 框架开发的简单 Restful API 为例,分别介绍如何使用 cURL 和 Postman 对其进行最基本的功能测试,目的是让你对 API 测试有一个基本的感性认识。

基于 Spring Boot 构建的 API

因为基于 Spring Boot 从 0 到 1 构建一个 API,并不是本文的重点,为了不影响你对文章主要内容的把握,我直接采用了一个预先开发好的 Account API 为例展开讲解。你可以从https://github.com/SpectoLabs/spring-cloud-contract-blog下载完整的代码。
这个 Account API 的功能非常简单,就是基于你提供的 ID 值创建一个 Account 对象,并返回这个新创建 Account 对象。
比如,如果你的请求是“account/ID008”,那么返回的 response 就应该是“{“id”:“ID008”,“type”:“friends”,“email”:“[email protected]”}”。
这个 Account API 的功能逻辑实现非常简单,图 1 和图 2 列出了主要的代码逻辑。
图 1 中,代码的第 21 行说明了 API 的 endpoint 以及对应的操作是 GET 方法,第 22 行明确说明了 GET 方法具体的业务逻辑是由 accountService.getById() 方法实现的。
图 1 RestController 的实现
图 2 中,代码的第 8 行实现了 accountService.getById() 方法,具体逻辑就是返回一个以传入 ID 为 ID 的 Account 对象。
图 2 具体业务逻辑的实现
我推荐使用 IntelliJ 打开这个下载的项目,然后直接启动其中的 account-service。启动成功后,account-service 会运行在本地机器的 8080 端口。启动成功后的界面如图 3 所示。
图 3 成功启动基于 Spring Boot 的 Account API

使用 cURL 命令行工具进行测试

首先,你需要下载安装 cURL,然后就可以通过以下命令发起 Account API 的调用。调用结束后的界面如图 4 所示。
curl -i -H "Accept: application/json" -X GET "http://127.0.0.1:8080/account/ID008"
图 4 使用 cURL 测试 Account API
这行命令中参数的含义如下:
第一个参数“-i”,说明需要显示 response 的 header 信息;
第二个参数“-H”,用于设定 request 中的 header;
第三个参数“-X”,用于指定执行的方法,这里使用了 GET 方法,其他常见的方法还有 POST、PUT 和 DELETE 等,如果不指定“-X”,那么默认的方法就是 GET。
最后“ http://127.0.0.1:8080/account/ID008 ”,指明了被测 API 的 endpoint 以及具体的 ID 值是“ID008”。
当使用 cURL 进行 API 测试时,常用参数还有两个:
“-d”:用于设定 http 参数,http 参数可以直接加在 URL 的 query string,也可以用“-d”带入参数。参数之间可以用“&”串接,或使用多个“-d”。
“-b”:当需要传递 cookie 时,用于指定 cookie 文件的路径。
需要注意的是这些参数都是大小写敏感的。
了解了这几个最常用的参数后,我再来分析一些最常用的 cURL 命令以及使用的场景,包括 Session 的场景和 Cookie 的场景。
第一,Session 的场景
如果后端工程师使用 session 记录使用者登入信息,那么后端通常会传一个 session ID 给前端。之后,前端在发给后端的 requests 的 header 中就需要设置此 session ID,后端便会以此 session ID 识别出前端是属于具体哪个 session,此时 cURL 的命令行如下所示:
curl -i -H "sessionid:XXXXXXXXXX" -X GET "http://XXX/api/demoAPI"
第二,Cookie 的场景
如果是使用 cookie,在认证成功后,后端会返回 cookie 给前端,前端可以把该 cookie 保存成为文件,当需要再次使用该 cookie 时,再用“-b cookie_File” 的方式在 request 中植入 cookie 即可正常使用。具体的 cURL 的命令行如下所示:
// 将cookie保存为文件
curl -i -X POST -d username=robin -d password=password123 -c ~/cookie.txt "http://XXX/auth"
// 载入cookie到request中
curl -i -H "Accept:application/json" -X GET -b ~/cookie.txt "http://XXX/api/demoAPI"
最后,需要特别说明的是,cURL 只能发起 API 调用,而其本身并不具备结果验证能力(结果验证由人完成),所以严格意义上说 cURL 并不属于测试工具的范畴。但是由于 cURL 足够轻量级,经常被很多开发人员和测试人员使用,所以我在这里做了简单的介绍。
接下来,我们再来看看如何使用目前主流的 Postman 完成 API 测试。

使用图形界面工具 Postman 进行测试

Postman 是目前使用最广泛的 Http 请求模拟工具之一,常常被用于 Web Service API 的测试。
早期的 Postman,是以 Chrome 浏览器的插件(plugin)形式存在的,最新版本的 Postman 已经是独立的应用了。我猜想是因为这个工具的应用日益广泛,所以才有了今天的独立版本。
你可以通过官方网站下载对应于 Mac、Windows 和 Linux 操作系统的不同版本,截止文章写作完成时,最新的 Mac 版本是 6.2.2。
接下来,我就会以 Mac 6.2.2 版本为例,跟你分享如何用 Postman 完成你的 API 测试。如果你使用浏览器的 plugin 版本,或者是基于其他操作系统的版本,这都没问题,基本的操作和步骤都是一样的。
具体的操作,主要包括:
发起 API 调用;
添加结果验证;
保存测试用例;
基于 Postman 的测试代码自动生成。
第一步,发起 API 调用
我们的目标是对 Account API 做测试,所以这里你需要选择 Postmant 的“Request”模块。进入相应界面后,你需要按照图 5 的提示依次执行以下三步操作,发起 Account API 的调用。
在 endpoint 输入框中输入“http://127.0.0.1:8080/account/ID_008”;
选择“GET”方法;
点击“Send”按钮发起 API 调用。
图 5 Postman 发起 Account API 的测试
完成以上步骤后,界面如图 6 所示。我们看到返回的 response 默认以 JSON 文件的形式显示在下面的 Body 中。
图 6 Postman 执行 GET 后的界面
这样就完成了一次 Account API 的调用,是不是非常简单。但问题是,这只是一个 API 调用,并没有对调用结果进行自动化验证。接下来,我们就加上结果验证的部分,一起看看会有什么效果。
第二步,添加结果验证
在 Postman 中添加结果验证也非常方便,假定我们在 Account API 测试过程中有以下四个验证点:
请求的返回状态码(Status Code)应该是 200;
请求的响应时间应该小于 200 ms;
请求返回的 response header 中应该包含“Content-Type”参数;
请求返回的 response body 中,“type”的值应该是“friends”;
那么,接下来我们一起来看看如何使用 Postman 来添加这四个验证点。
为此,我们首先打开“Tests”界面,然后在右下角的“SNIPPETS”中依次点击:
“Status code: Code is 200”
“Response time is less than 200 ms”
“Response headers:Content-Type header check”
“Response body: JSON value check”
完成以上操作后,“Tests”中会自动生成验证代码,接着只要按照具体的测试要求,对这些生成的代码进行一些小修改就可以了。
在这个例子中,你只需修改需要验证的 JSON 键值对即可,即代码的第 15 行。修改完成后我们可以再次点击“Send”按钮发起测试。测试通过的界面如图 7 所示,最下面的“Test Results”显示四个测试全部通过。
图 7 测试通过的界面
第三步,保存测试用例
测试通过后,我们往往希望可以把这个测试 request 保存下来,以方便后续使用,为此 Postman 提供了保存测试 request 的功能,并提供了 Collection 来分类管理保存多个测试 request。
Collection 是用来保存测试 request 的一个集合,Collection 内部还可以建立目录结构以方便进一步的分类和管理。
这里我们点击“Save As”按钮,在弹出的对话框中可以建立 Collection,并且可以命名测试 request 并将其保存到 Collection 中。
我建立了“API Test Demo”的 Collection,并且将刚才的测试 request 命名为“AccountAPI”保存到这个 Collection 中。
以后再要使用这个测试 request 时,直接在 Collection 中打开它,即可使用。同时你如果申请注册了一个 Postman 账号,就可以很方便地在多个环境中共享这个 Collection 了。
第四步,基于 Postman 的测试代码自动生成
至此,你已经掌握了 Postman 最基本的使用方法,但还有一个问题没有解决。很多时候,你希望将你的测试 request 作为回归测试用例集成到 CI/CD 的流程中,这就要求可以通过命令行的方式执行你的测试。为了达到这个目的,目前有两种做法:
将 Postman 中的测试 request 用自动化的方式直接转换成 API 测试的代码。 目前 Postman 已经支持这个功能了,可以将保存的测试 request 自动化转换成常见测试框架直接支持的代码,而且支持多语言。
比如,基于 Java 的“OK HTTP”和“Unirest”,基于 Python 的“http.client”和“Requests”,基于 NodeJS 的“Native”“Request”和“Unirest”,基于 JavaScript 的“JQuery AJAX”和“XHR”等等。你可以点击如图 8 所示的“Code”按钮进入代码生成界面。
图 8 自动生成 API 测试代码
利用 Newman 工具直接执行 Postman 的 Collection。 你需要先将 Postman 中的 Collection 导出为 JSON 文件,然后执行以下命令行。
newman run examples/sample-collection.json;

如何应对复杂场景的 API 测试?

我在前面分享的 Restful API 测试案例中,只涉及到了最基本的 API 的测试方法,而且测试场景也很比较简单(只是单个 API 的调用)。
但在实际项目中,除了这种单个 API 的测试场景外,还有很多复杂场景的 API 测试。所以,为了解决你在实际项目中可能会碰到的一些问题,我再和你聊聊目前一些常见的典型复杂场景,以及相应的测试思路和方法。
测试场景一:被测业务操作是由多个 API 调用协作完成
很多情况下,一个单一的前端操作可能会触发后端一系列的 API 调用,由于前端测试的相对不稳定性,或者由于性能测试的要求,你必须直接从后端通过模拟 API 的顺序调用来模拟测试过程。
这时,API 的测试用例就不再是简单的单个 API 调用了,而是一系列 API 的调用,并且经常存在后一个 API 需要使用前一个 API 返回结果的情况,以及需要根据前一个 API 的返回结果决定后面应该调用哪个 API 的情况。
好在,我们已经实现了 API 的调用和结果解析的代码化,这也就意味着我们可以很灵活地直接用代码来处理这些场景了。 比如,通过代码将上个 API 调用返回的 response 中的某个值传递给下一个 API,再比如根据上一个 API 的返回结果决定下一个应该调用哪个 API 等。
除此之外,我们还需要迫切解决的一个问题是:如何才能高效地获取单个前端操作所触发的 API 调用序列。
解决这个问题的核心思路是,通过网络监控的手段,捕获单个前端操作所触发的 API 调用序列。比如,通过类似于 Fiddler 之类的网络抓包工具,获取这个调用序列;又比如,目前很多互联网公司还在考虑基于用户行为日志,通过大数据手段来获取这个序列。
测试场景二:API 测试过程中的第三方依赖
API 之间是存在依赖关系的,比如你的被测对象是 API A,但是 API A 的内部调用了 API B,此时如果由于某种原因,API B 在被测环境中处于不可用状态,那么 API A 的测试就会受到影响。
在单体架构下,通常只会在涉及到第三方 API 集成的场景中才会遇到这个问题,所以还不算严重。但是,在微服务架构下,API 间相互耦合的依赖问题就会非常严重。
解决这个问题的核心思路是,启用 Mock Server 来代替真实的 API。那么,Mock Server 怎么才能真实有效地模拟被替代的 API 呢?这个问题,我会在分享《紧跟时代步伐:微服务模式下 API 测试要怎么做?》这个主题时,和你详细探讨。
测试场景三:异步 API 的测试
异步 API 是指,调用后会立即返回,但是实际任务并没有真正完成,而是需要稍后去查询或者回调(Callback)的 API。
一直以来,异步 API 测试都是 API 测试中比较困难的部分。在我看来,对异步 API 的测试主要分为两个部分:一是,测试异步调用是否成功,二是,测试异步调用的业务逻辑处理是否正确。
异步调用是否成功,这个还比较简单,主要检查返回值和后台工作线程是否被创建两个方面就可以了。
但是,对异步调用业务逻辑的测试就比较复杂了,因为异步 API 通常发生在一些比较慢的操作上,比如数据库 I/O、消息队列 I/O 等,此时测试往往需要去验证数据库中的值、消息队列中的值等,这就需要测试代码具有访问和操作数据库或者消息队列的能力。
在实际工程项目中,这些能力一般会在测试框架级别提供,也就是说要求 API 测试框架中包含对应的工具类去访问和操作数据库或者消息队列等。

总结

通常情况下,无论你采用什么 API 测试工具,基本的测试步骤往往都是三步,即准备测试数据(并不是所有的 API 测试都需要这一步)、通过 API 测试工具发起对被测 API 的 request、验证返回结果的 response。
接下来,我通过一个简单的 Restful API 测试为例,和你分享了 cURL 和 Postman 这两个常用 API 测试工具的使用。
其中,cURL 只具备发起 API 调用的功能,而不具备结果验证能力,所以严格地说它并不属于测试工具的范畴。Postman 常常被用于 Web Service API 的测试具体的操作,测试流程主要包括:发起 API 调用、添加结果验证、保存测试用例、基于 Postman 的测试代码自动生成。
最后,为了帮你应对实际工程项目中复杂的 API 测试场景,我分享了被测业务操作是由多个 API 调用协作完成、API 测试过程中的第三方依赖、异步 API 的测试,这三个复杂场景下的测试思路和方法。

思考题

单个 API 测试是比较简单的,但在实际项目中,往往存在按时序的 API 调用以及异步 API 调用,这类 API 你是如何测试的?遇到过什么难题,又是如何解决的?
感谢你的收听,欢迎给我留言讨论。
分享给需要的人,Ta购买本课程,你将得20
生成海报并分享

赞 14

提建议

上一篇
21 | 移动测试神器:带你玩转Appium
下一篇
23 | 知其然知其所以然:聊聊API自动化测试框架的前世今生
unpreview
 写留言

精选留言(39)

  • sylan215
    2018-08-17
    1. 这么一对比的话,Postman 完胜 cURL,实际情况也是 Postman 的使用更加的广泛,特别是开发相互之间做接口对接时,Postman 可以很方便的甩锅。 2. Postman 的 Pre-request Script 功能,可以支持变量的传入,应该也可以解决 API 调用的时序问题,比如前一个接口的返回值作为当前接口的入参。 3. Postman 如果设置了多个 Workspace,并且有 Collections 在不同 Workspace 之间分享的话,貌似还是同一份,从一个 Workspace 删除后,另一个 Workspace 也会被同步删除,有点坑,千万注意,还好的就是 Postman 的 web 版提供了 Trash 可以恢复不小心错删的内容,前段时间刚刚踩过这个坑,请关注。 4. 如果是简单的 URL 测试,我觉得使用 Python 的 requests 库做下分层设计,应该也是比较简单的,而且会更加灵活,也更适合做为日常的回归执行,这样也可以解决茹老师提到的时序问题和异步调用问题了。 以上,欢迎沟通交流,公众号「sylan215」
    展开

    作者回复: 非常高质量的留言,👍,对于第四点,现在其实有个叫httprunner的api框架,底层就是封装了python的requests,然后通过写配置而不是写代码来完成api测试,其中就可以处理时序,传参数等问题,但是异步api还是没有太好的方法

    共 2 条评论
    28
  • 豆豆
    2018-11-12
    这课的展现效果不好,有种茶壶煮饺子的感觉
    22
  • 文大头
    2018-08-23
    说到异步,我现在的项目刚好有个场景,我使用jmeter压API,需要调用异步API创建一个东西,然后后台线程进行一系列操作后,更新这个东西的状态,我前端要等到他的状态变化后,再做下一步操作。具体做法是jmeter发起了创建操作后,循环执行一个查询状态操作,等到发现状态正常后再进行后续操作,或者状态异常/超时后报错。有意思的是,如果后端数据库是个集群,这样测试,还能经常发现数据库集群的node间数据不同步的问题。

    作者回复: 如果异步api没有callback接口,那么就只能用你所说的我方式,很棒的分享

    共 2 条评论
    16
  • arthur
    2018-08-26
    我们的项目中也有异步API调用的情况,作为开发,他们也需要知道操作什么时候完成,然后做出后续操作。这边的异步,开发都会在数据库的一张表插入运行信息,完成后做出相应修改。所以测试的时候,也是通过查数据库来判断异步是否完成。
    9
  • 大QA
    2018-08-24
    小白请教个问题,Postman 可以批量执行(run),为什么还需要newman ?是为了持续集成吗?

    作者回复: postman可以批量执行,Newman的目的是为了可以从命令行发起测试,的确是为了持续集成

    10
  • 楚耳
    2018-08-17
    老师能深入讲解下Mock这个东西嘛,我看你好几篇文章都提到这个东西。还有这篇API 测试感觉完全没尽兴,现在公司都是自己用python 写代码测试API ,能讲讲自己开发一套api 测试框架的相关设计吗

    作者回复: Mock其实你可以简单想象成为了辅助你做测试而使用的真实api的替代品。如果用python一般都是用requests框架,这个框架的使用非常简单明了。api测试框架的设计就是下一篇文章的主题,我会从最简单的api框架讲起,逐渐过渡到先进的做法,期待一下吧

    10
  • DON G
    2018-08-17
    异步api测试这块不太理解,我们现在基本都是用ajax实现异步请求,接口测试的时候就按照普通的接口进行测试,验证返回值,并没有对异步调用业务逻辑测试~ 🤔

    作者回复: 你说的这个异步和我说的异步应该不是一个概念,我这里指的异步api指调用后会立即返回,但是此时真正的任务还没有完成。

    5
  • 静静张
    2018-08-19
    老师,这里的异步是多线程的意思吗?
    共 2 条评论
    3
  • zyl
    2020-12-15
    摘要: API测试的基本步骤: 1. 准备测试数据(可选) 2. 通过API测试工具发起对被测API的request 3. 验证返回的response Postman是目前使用最广泛的http请求模拟工具之一,常被用于Web Service API的测试,具体操作如下: 1. 发起API调用 2. 添加结果验证 3. 保存测试用例 4. 基于Postman的测试代码生成 如何应对复杂场景的API测试? 场景1:被测业务是由多个API调用协作完成 通过API调用和结果解析的代码化就可以灵活处理上述场景。通过抓包的方式获取单个操作触发的API调用序列。 场景2:API测试过程中的第三方依赖 启用mock server来代替真实API就能实现 场景3:异步API的测试 异步API指的是调用后立即返回,但是任务没有完成,需要后续去查询或者回调的API. 异步API的测试主要分为两部分: 1. 测试异步调用是否成功 2. 测试异步调用的业务逻辑处理是否正确。
    展开
    4
  • 捷后愚生
    2020-07-15
    学习到了,api测试,其实就是我们平时所说的接口测试。 如何应对复杂场景的 API 测试?这部分总结得非常好,可以直接拿来应对面试啊 ! 接触了python+ requests、python+httprunner,这两个都是比较容易上手的。 其实接口测试时也会用到PO思想,这篇文章没有介绍,不知道后面老师会不会提到。
    3
  • Gavin
    2020-04-20
    最近也学习接口测试,不过是基于Jmeter这款工具。 之前我理解的接口测试就是对照接口文档,填写对应的请求,参数,通过断言验证返回结果。 不过对于不规范的接口文档,自己通过Fiddler抓包查看时不确定哪些请求有用,哪些请求没什么用。 而且对于那种订单提交需要传很多参数时,看着有点懵。 简单接口参数,一些常用的可能通过变量获取使用,但那种提交需要很多参数的,不知道如何下手了。
    展开
    2
  • 帝痕
    2020-03-25
    长期来看还是使用测试框架进行API测试会更加合适,特别是很多公司还有非HTTP协议的情况下(如thirft、dubbo、hsf等)
    2
  • 不将就
    2020-03-18
    星主,您好,请问接口测试都要做数据库检查吗?
    2
  • 小寞子。(≥3≤)
    2019-03-22
    不知道有没有听过lisa,CA。 我们在用这个做中间件测试。 测试各种API。 包含了消息队列。 SOAP。 各种不同的call。。 要自己建立stub来连接中间件之后做自动化测试。。。。 也是遇到了很多挑战。
    2
  • 芭蕉桑
    2018-11-10
    老师,我负责测试的一款APP最近完成了API测试的基本框架和测试代码,已经在迭代中试用了。但手工测试的用例编写数量和人力投入并没有减少。想请教一下老师,API测试如何运用才能有效地减少手工测试的人力投入呢?辛苦老师解答一下。
    共 2 条评论
    2
  • family
    2018-08-21
    能讲一下sdk的自动化测试么?
    2
  • 学无止境,唯乐学习
    2020-09-15
    时序API调用,最常见在场景自动化,或则登录接口,场景自动化我之前应用了方法调用方法的方法,可以按照一个场景对应一个测试用例。登录的话,testNG框架有对应的注解BeforeSuite(在test suite中的所有test运行之前运行,只运行一次)然后缓存获取的token,可以再BeforeSuite注解的方法里,查询缓存在Redis里的token,有的话执行登录方法,无执行登录方法
    1
  • 桃夭夭
    2019-01-05
    老师,这个API测试也可以用testng来实现吧,是不是接口测试和API测试基本上算是同一个东西?

    作者回复: 可以用testng,testng就像是个测试执行的框架。api是接口的一种类型,接口的定义会更加宽泛

    1
  • 豆豆
    2018-11-12
    这种课应该录制成视频,只是看图说话,没有演绎的过程理解起来很费劲。
    1
  • 小老鼠
    2018-10-27
    1、老师为什么不用interface test,而用API test 2、Python 中的requests 您感觉如何?
    1