从基本概念上说,API的作用是:通过任何形式的通信手段,促进两种不同应用程序之间实现交互。例如,在Web应用上所使用到的API,我们往往称之为“Web服务”。如今,随着应用技术的进步和种类的增多,API已经成为了编程代码中的重要组成部分。在开发各种应用项目时,编程人员往往会通过使用API来与数据库或其他的模块进行通信。这就是为什么作为测试人员的我们,必须通过测试API,以求获得最大的测试覆盖率(test coverage)的原因。
而作为集成测试的一部分,API自动化可以协助加速测试的进程并提高效率。由于目前大多数公司都在业务层面上使用到了RESTful微服务和API,因此对于API的测试已经成为了任何发布测试计划中的关键环节之一。
简单来说,API实际是一种服务,它可以帮助两种不同的应用程序实现顺畅的相互通信。大多数API被用于抽象各种业务逻辑,并引导到应用程序访问其对应的数据库。
从逻辑上讲,我们可以将整个软件系统分为三个层次:
1. 表示层 - 这是展示给最终用户的某个用户界面(GUI)。质量保证人员(Quality Assurance,QA)对于该层次进行功能测试。
2. 业务层 - 这是通过编写逻辑代码,来实现各种应用的用户接口。就实现技术而言,各类代码和算法属于在这个层面上。当然API也处于这个层次。
3. 数据库层 - 存储的是应用程序的各种数据信息。
换句话说,API是软件互联世界的中枢神经。它通过运用各种工具、协议、标准和代码集,将数字世界“粘合”在一起。由于API不但动态灵活,而且功能强大,因此它让各种软件产品更为简便、更具有移动性,不同组件能够以一种无缝集成的方式进行协同运作。那么,针对API的测试则可以从服务级别和集成级别两个方面进行展开。
API的测试策略
就不同人员的关注点而言,开发人员一般倾向于只测试他们正在开发的软件功能;一般测试人员则只负责做功能性的单元测试、以及端到端的协同测试。然而在如今DevOps的持续开发与测试环节中,测试人员更应该专注于在软件使用过程中所进行的各种API调用,以便观察和记录在系统做出响应之前所接收的不同输出。而且,其中最重要的是:应测试API在不同条件下是否能返回正确的响应或输出值。一般而言,此类输出可以被分为如下三类:
- 通过(成功)或失败状态
- 数据或信息
- 调用另一个API
当然,也可能根本没有任何输出、或发生了完全不可预测的结果。因此,测试人员就要在整个应用程序的开发过程中起到关键性的作用,他们需要通过数据驱动型测试,来提高整体测试的覆盖率和准确性。
API测试的类型
正如我们通常需要根据目标产品具有哪些功能,提前设定好进行何种类型的测试一样,测试人员往往也需要首先确定好将在API上执行哪种类型的测试。如下是常见的API测试种类:
- 单元测试 - 测试单个操作的功能。例如,Google地图通过提供地理编码类型的API,以获取任意位置的经度和纬度。其后台实际上是将地址信息作为输入,并返回纬度和经度的数值。那么在针对该API的单元测试中,测试人员可以通过输入不同的位置信息来验证其各种输出结果。
- 功能测试 - 此类测试主要关注于API的本身功能,即:通过各种测试用例,来验证HTTP响应的程序代码、响应的准确性、API可能返回的任何错误代码等方面。
- 负载测试 – 在有多个用户同时使用某个应用程序,并引发了API需要处理大量数据的情况下,此类测试是必需的。它通过增加API的调用频率,以暴露可能出现的崩溃、或无法“承压”等状况。
- 安全测试 - 由于API会被用于在两个不同的应用程序之间创建连接,而使用API的核心目的就是为了将某个应用程序的数据库相对于另一个进行抽象或隐藏,因此安全测试尤为重要。测试用例一般包括:授权检查、会话管理等方面。
- 互操作性测试 – 此类测试的目的是保证API能够被应用程序按需访问到,例如SOAP API就属于此类。
- WS(Web Service)合规性测试 – 在对于API的测试过程中,我们应当确保诸如:WS-Addressing、WS-Discovery、WS-Federation、WS-Policy、WS-Security和WS-Trust等标准能够被正确地采用和实施。
- 渗透测试 - 这是从外部攻击源来查找API的漏洞。
Web服务与API协议
上面我们提到了Web服务,它主要是由两种类型的服务(或称为协议)所组成:
REST(Representational State Transfer) - 是一种轻量级的协议,它使用URL来获取所有需要的信息。与下面将要介绍的SOAP相比,它不但更新了、而且克服了SOAP上存在的所有问题。REST使用如下四种HTTP方法来执行各项任务:
1. Get - 获取信息。例如,在位置映射的API中获取经度和纬度的信息。
2. Post - 在资源中插入一些数据。
3. Put - 更新目标资源。
4. Delete - 从资源中进行删除。
由于其架构简单且轻巧,因此REST如今已被广为使用。
SOAP(Simple Object Access Protocol) API - 它使用XML来进行消息交换。而执行该任务所需的所有信息,都是由Web服务描述语言(Web Service Description Language,WSDL)所给定的。SOAP的扩展性和与XML相关的标准性,造成了SOAP相对来说比较“重”。而它相比REST的优势在于:它具有内置的错误处理功能,并且可以与其他协议(如SMTP)协同使用。
API的测试步骤
市面上有许多针对API的测试工具。在测试人员接手API之初,他们应当先参考其相应的文档,以判定目标是属于REST、还是SOAP API、或者它根本就不是基于Web的API,这些详细的信息都应当被记录在配套的文档之中。因此,API的测试基本流程为:
1. 参考文档(上面已经提及)
2. 先编写功能性、或服务级别的相关用例
3. 编写各种集成测试
4. 在API足够稳定、且完成了上述的测试步骤之后,我们可以开始进行安全、性能和负载类型的测试。
具体说来,我们可以按照如下的顺序进行:
1. 典型的API文档一般会包含与API相关的所有信息,其中包括:请求的格式、响应的类型、错误的代码、用到的资源、必需的参数、可选的参数、headers等方面。而对于这类文档,我们则可以使用诸如开源的swagger、Dapperdox和ReDoc等工具来进行日常维护。
2. 之后我们就可以着手为API编写服务级别的测试用例了。例如,如果某个API使用了n个参数来获取响应,其中m是必要参数,而其他都是可选参数,那么其对应的测试用例应该去尝试不同的参数组合,以验证各种响应结果。而另一种测试用例则可能需要验证headers;和在不启用身份验证的情况下运行API,以检验其产生的错误代码。
3. 接下来便是集成测试的步骤了。您需要测试目标API的所有依赖项、及其功能。同时,我们还可能需要测试该API的各种响应,从其他API、或方法处预计返回的数据,以及该API在失效时的各种状态与输出信息。
4. 一旦目标API的表现稳定、并完成了所有功能性的测试,那么测试人员就可以开始进行与负载、安全和性能相关的各种深度测试了。
API自动化测试工具
如今随着DevOps的盛行,我们通常在每次进行发布之前,都可能需要对一些测试用例,如回归用例,执行重复性的测试。因此,这就需要测试人员实现一些自动化的任务。
市面上有许多针对API自动化的工具,我们在此列举几个典型的:
- SOAP UI - 这是一款非常流行的API测试工具。您可以使用SoapUI来对目标API执行功能性、负载性、安全性和合规性等测试。
- Katalon Studio - 建立在Selenium和Appium基础之上的Katalon Studio,是一款免费的、且功能强大的自动化测试工具。它能够被用于执行Web测试、API测试和移动测试。
- Postman - Postman是一款免费的工具。您可以使用它来高效地开发和测试目标API的所有功能。
- Jmeter - 虽然测试人员主要会将Jmeter用于性能和负载方面的测试,但它在很大程度上也是可以被用到API的功能测试环节中。
- RestAssured – RestAssured实际上是一个基于Java的库,因此它可以被用于测试各种基于RESTful的Web服务。您可以将该库包含在现有框架中,直接调用其对应的方法,以获取JSON格式的响应,并最终执行各种所需的操作。
下面,我将通过一个实例来诠释API功能测试所需要遵循的基本步骤。在该示例中,我使用的是由CloudQA所提供的一款较为新颖且流行的工具--TruAPI。
步骤1
为了产生一个API请求,您首先需要选择一种Method Type,并在此粘贴目标API的URL。您既可以按下发送按钮,将请求发送到给目标API;也可以按下Add API Test按钮,以保存该请求:
为了方便看到效果,您可以试着使用如下Method Type和API URL:
- Method Type: GET
- API URL: https://um5fdww2pj.execute-api.us-east-1.amazonaws.com/dev/todos
第2步 - API的请求信息:
- 大多数API都需要一些额外的输入,才能执行对应的请求。诸如:参数、Headers、Body(JSON)等。
- 因此,为了给请求添加各项参数,您可以选择相应的Parameters选项卡,然后点击“Add Parameter”按钮,以添加所需的信息。
第3步 - 使用身份验证发送API请求:
- 如果您的目标API需要身份验证的话,您可以选择Authorization选项卡,从下拉列表中选择BasicAuth(其默认设置为Noauth),然后输入用户名和密码,那么您就可以发送带有身份验证的请求了。
- 相对应地,每个API的响应也都包含不同的值,例如:状态代码、body、headers、以及完成API请求的时间。下面,我们来对API的响应进行详细讨论。
添加断言(Assertions):
在自动化过程中,使用断言来验证各种输出是非常重要的。如果您想在API Runner中添加断言,那么请选择Assertions选项卡。在此,您可以添加一到多个断言。
下面是添加断言的简单步骤:
1. 选择响应类型
2. 选择断言的条件
3. 输入需要检查的值
4. 完成断言的添加
变量:
Variables选项卡可以被用于存储那些根据API请求所产生的响应接收值。如果您想保存各种响应,请选择Variables选项卡,然后按照以下步骤进行操作:
1. 添加变量
2. 为变量命名,以便其他团队容易理解
3. 输入来自响应body并存储着数值的JSON路径
4. 如果您想将变量中的存储值用作预期的断言,则可以在任何其他API的请求中使用变量:_name
查看或执行某个已保存的API请求:
- 您可以在API Runner页面上,使用View Saved Tests按钮,来查看各种已保存的测试。
- 选中一到多个已保存的API测试,并默认运行它们。这些测试会显示上一次执行后的运行状态信息。
- 而结果将显示在API执行历史的记录中。
上面我们介绍的只是一个单独的API执行与自动化。而在真实的场景中,我们经常需要创建包含所有回归测试用例在内的API套件,并将其作为回归测试的一部分来运行。在敏捷开发的理念中,准备好相应的套件是至关重要的,只有这样才能更好地与持续集成/持续交付(CI/CD)进行整合。
另外,CloudQA附带有丰富的说明文档。而且CloudQA提供的所有工具都是与“无代码自动化(Codeless automation)”的理念相一致的。这也就方便了那些手动测试人员的使用。详细文档,请参见:https://doc.cloudqa.io/TruAPI.html。
原文标题:The Know-Hows of API Testing,作者:Ruchira Shukla