“测试代码”通常组织成一条路径,从单元测试开始,继续进行集成/端到端测试,最后进行用户验收测试。在这条路径的开始,单元测试做两件事——它确认:
“被测代码”(CUT)在输入时做正确的事情
CUT 将正确的数据传递给处理链中的下一个数据
之后,您继续进行集成测试,确认“假冒”是否正常工作(大概只有在对“处理链中的下一个事物”进行单元测试以确认它正确完成其工作之后)。
有了 API,单元测试可能会成为计划失败的地方。因为 API 是处理链的接口,所以很容易混淆 API 的单元测试和整个处理链的集成测试。有效的 API 测试策略可以防止这种情况发生。
为了演示如何有效地管理您的 API 测试,我将介绍 API 单元测试策略(使用 [ Telerik Test Studio for APIs)来演示有效的 API 策略在现实生活中是什么样子的。
API 单元测试
与任何其他测试集一样,API 测试遵循 Arrange-Act-Assert 模式。然而,与其他测试不同的是,您可以在不编写任何代码的情况下开始测试您的 Web 服务 API——例如,使用 Azure 的API 管理服务,您可以在根本不编写任何代码的情况下定义您的 API。因此,您从构成 API 的 URL 而不是代码开始 API 测试。
安排
构成 RESTful 服务 API 的 URL 通常共享一个基础,所有对服务的请求都使用该基础的变体。例如,这两个 URL 可能支持对客户服务的所有基本 CRUD 操作:
http://customers:检索所有客户;使用提供客户 ID 的系统添加客户
http://customers/A123:检索、更新或删除客户;添加客户,指定客户 ID(本例中为客户“A123”)
对于本案例研究,我将使用http://customers作为我的基本 URL。Test Studio for APIs 通过创建项目级变量(按照惯例称为 base-url,但您可以随意调用该变量)来支持该设计。这意味着我需要用于我的基本 CRUD 操作的两个 URL 如下所示(API 的 Test Studio 使用双法语大括号来标记测试中的变量):
{{base-uri}}:检索所有客户;使用提供客户 ID 的系统添加客户
{{base-uri}}/A123:检索、更新或删除客户;添加指定客户 ID 的客户
设置我的项目并使用其基本 URL 创建我的第一个测试在 Test Studio for APIs 中看起来像这样:
图片 1
行为
API 测试的 Act 阶段包括使用基本 URL、HTTP 动词(GET、POST 等)以及请求正文和/或标头中可能包含的某些值发出 HTTP 请求。
显而易见的第一个测试是带有基本 URL 的简单 GET 请求(我的客户服务中的“获取所有客户”请求)。为了在 Test Studio 中针对 API 实施第一个测试,我将向我的项目添加一个 HTTP 请求步骤,并将其动词设置为 GET,并将其 URL 设置为仅 base-url 变量。第一个测试看起来像这样:
图 2
断言
对于 RESTful API 测试,Assert 阶段从检查 HTTP 响应的状态代码开始。此外(如果它对应用程序有影响),您可以检查响应正文或标头中的值。在 Test Studio for APIs 中,我使用 HTTP 请求的验证选项卡中的设置来检查我的结果。此时(记住没有与此 API 关联的代码),我只想检查响应中的状态代码是否等于 200:
图 3
由于服务甚至还没有创建,运行这个测试可能看起来很愚蠢。但是,如果我运行这个测试并且它成功了,那么我就知道我有一个无用的测试:它无法检测到失败。现在运行测试可以快速轻松地检查我的测试质量。此外,在 Test Studio for APIs 中,运行测试很容易:只需单击“运行”按钮即可。
我这样做了,不出所料,测试失败了。API 的 Test Studio 在失败的步骤、测试和项目旁边显示传统的红色信号灯图标:
图 4
最终,这个测试会变得有用(这就是它被命名为“拒绝未经授权的用户”的原因)。不过现在,我已经证明这个测试可以区分成功和失败。
测试认证
下一步是开始编写 API。这将根据您用于构建服务的开发平台而有所不同:对于 ASP.NET/ASP.NET Core/.NET,下一步将包括创建控制器……但我将仅此而已。我不会在控制器的方法中放置任何超出让这些控制器编译所需的代码(可能只是返回 200 状态代码的返回语句)。通过 Azure 的 API 管理,我将定义 API,并且可能会使用入站策略返回模拟结果。
此时我不需要任何代码,因为我要测试的只是我是否可以成功访问我的 API。更准确地说:这是我发现我是否正确处理身份验证的地方。假设我的 API 有适当的身份验证/授权(并且应该),当我重新运行我的测试时,我现在应该得到一个 401 Unauthorized 状态代码。
此时,在 API 的 Test Studio 中,我将验证选项卡上的状态代码更新为 401,以便拒绝显示为“通过测试”。当我现在重新运行我的测试时,我已经证明我的服务拒绝未经授权的用户。
这导致明显的第二个测试:授权用户可以访问该服务吗?如果我使用基本身份验证,Test Studio for APIs 将在给定用户名和密码的情况下生成身份验证标头(或者,它将生成客户端 ID 和密码以支持 OAuth)。
这是一个比那两个更简单的示例,它将基本订阅类型标头合并到我将用于第二次测试的请求中: