# 为什么你不能只做api测试


翻译了一篇[Limitations of API-only testing: Why it shouldn’t be your sole testing strategy](https://www.checklyhq.com/blog/limitations-of-api-only-testing/)，这篇文章的核心观点是讨论为什么不能只做 api 级的测试，挺有道理的，适合泛读以及扩充观点库。

前几天我收到了一篇独特的文章，它提出了一个大胆的观点：“API 测试比 UI 测试更好”。在软件世界中，像“A 比 B 更好”这样的绝对陈述很少成立。“这取决于”才是大多数技术问题的答案，因为有原因。

让我们比较 API 和 UI 测试，并讨论为什么一个不如另一个。这两个方法是“敌人还是朋友”，但永远是不同的。这很好。

### API 测试和 UI 测试——两种截然不同的挑战

当你比较 API 和 UI 测试并说一个更好时，这句话背后是什么？人们经常比较这两种测试方法的可扩展性、稳定性或可维护性。然而，这些比较都没有价值，因为 API 和 UI 测试非常不同。

根据我的经验，这些比较的基础总是相同的：API 测试比 UI 测试更容易维护。让我们深入研究一下，看看为什么这并不重要！

### API 测试易于实现

API 测试比 UI 测试更容易维护的说法是成立的。在最简单的形式中，你甚至可以用你喜欢的编程语言编写一个 50 行的脚本，对本地或暂存环境进行 HTTP 调用，并解析 JSON 来评估响应是否正确。使用 HTTP 并不难。你甚至可以使用一些 shell 魔法来连接请求并将脚本并行化，以单个命令覆盖整个 API 表面。

很快，你会意识到你需要测试报告、合适的测试运行器和高级测试断言。此外，没有人知道如何处理你自制的测试脚本。因此，你将转向 Postman 或类似的工具。恭喜你！现在，你可以创建 HTTP 请求并测试整个 API 表面。而且可以扩展！这很棒！

我可以大胆地说，用于验证 API 的测试工具今天已经足够好了。API 测试的复杂性有限，实现是一个已经解决的问题。

那么，UI 测试呢？

### UI 测试仍然难以编写和维护

无论使用什么工具，测试 Web UI 都是具有挑战性的。主要原因是测试网站的复杂性远高于测试 API。

即使是微软的 Playwright 等现代浏览器自动化工具也通过出色的 DX（开发人员体验）、跨浏览器测试功能和用户优先自动化的全新方法简化了 UI 测试，但 Web UI 测试仍然是一头难以驯服的野兽。为什么？

首先，控制浏览器打开页面并评估渲染的 UI 比进行 HTTP 调用复杂得多。你知道如何进行脚本化的 HTTP 请求吗？很可能你会的。你知道如何不使用自动化库来控制浏览器和验证渲染的页面吗？我不会。但是，自动化浏览器并不是 UI 测试中的唯一问题。

在过去十年中，现代前端应用程序的技术复杂性已经无限增长。你还记得前端由简单的 HTML 和一些 jQuery 代码组成的时候吗？测试 HTML GET 请求和随后的表单提交 POST 请求非常简单，因为 UI 交互是可预测且复杂性有限的。

如今，一个网站包含 2MB 以上的压缩资源，每次页面加载会发出 60 多个请求。平均而言，至少有 20 个请求是 JavaScript 资源，它们添加了自定义功能。一个简单的注册表单很容易在竞争中对应用程序进行一系列额外请求，以迫使其进入不同的状态，并添加表单验证、动画或控件。希望没有脚本会卡住卡，否则应用程序可能会进入白屏甚至是无法正确渲染。

简而言之，在现代 Web 应用程序中发生了很多事情，无论使用什么工具，测试现代 Web 都很难。很遗憾地告诉您：这不会很快改变。无论使用什么工具。

但这也意味着你应该为了易用性而选择 API 而不是 UI 测试吗？绝对不是！

### 您想通过测试策略解决什么问题？

将测试方法相互比较是错误的，因为每个产品都是不同的。每个应用程序都有不同的要求、为不同的客户提供服务，并使用不同的技术构建。没有单一的最佳测试方法——这总是取决于具体情况。软件开发和测试总是关于权衡取舍。

您的测试设置应该围绕一个问题展开：为什么要投资于自动化测试？您想从中得到什么？对这个问题的回答（而不是其他任何东西）将导致适合您的测试设置。

如果您正在开发面向开发人员的产品，那么您很可能提供 HTTP API。您是否应该测试其 endpoint？当然！您是否应该追求 100% 的测试覆盖率？只有您才能回答这个问题，因为编写和维护测试需要时间和精力。但是，如果您努力保持高可用性或与反复出现的 API 错误作斗争，那么良好的测试覆盖率不会对您造成任何损害。

但假设您的核心产品是基于定制 API 的用户界面。即使底层 API 正常运行，您的应用程序是否也可能崩溃？当然！前端代码中一个简单的分号缺失就可能使您的应用程序瘫痪。更不用说前端逻辑错误了。在这种情况下，承担 UI 测试的负担是否值得？我会说是的！

要编写哪些测试以及要测试哪些功能取决于您和您的产品。哪些功能不能被破坏？测试这些功能应该是最低要求。

### 高测试覆盖率错过重点

高测试覆盖率（无论是 API 还是 UI）如果不能防止您将关键的用户端错误发布到生产环境，那么它就失去了意义。如果您因为 API 测试“更好”而严格测试 API 表面，那就太好了！拥有测试仍然比没有测试好。

但是，如果您的测试套件未能使您尽快发布无 bug 软件，那么您必须质疑测试的目的。您是否在为自己进行测试？您是否在追求虚荣的数字，而不是使您能够向生产环境发布好东西？我多次犯过追求神圣但毫无意义的 100% 测试覆盖率的错误。

但你应该测试什么，平衡点在哪里？

### 自动化测试完全是关于用户体验的（并且永远都是）

我是否在说您不应该追求高测试覆盖率？一点也不。相反，我主张采用以用户和价值为导向的测试方法。您的客户都不在乎您的高测试覆盖率。他们唯一关心的是一个工作正常的产品。

如果您的 API 测试使您能够快速发布新功能并且不会破坏生产环境，那就去做吧。但如果您的测试套件存在盲点，您的应用程序可能会在您不知不觉的情况下崩溃，那么您最好消除这些盲点！

确实，UI 测试很难编写，因为它们处理的是高复杂性，但如果您为客户提供 UI，那么您至少应该知道它可以工作！不要让一个缺失的分号击倒你。而且，您是否需要测试所有 UI 功能并追求神圣的测试覆盖率？当然不是，但知道您上次的功能部署没有破坏关键的用户流程会让您睡得更好。相信我。

由您来定义需要多少测试才能自信地发布功能并赢得用户信任。

但说到信任，您的 API 和 UI 部署测试是否真的能防止您出现用户端的生产问题？我对此表示怀疑。

**部署测试不是您所希望的安全网**

假设您正在发布一个为全球受众提供服务的应用程序并依赖第三方 API。测试您的部署是否足以确保出色的用户体验？如果您的 API 依赖项之一宕机怎么办？您的应用程序是否会跟随？

如果答案是“是”，请注意部署测试可能无法满足要求，因为您的应用程序在生产部署后可能会（并且将会）崩溃。

我现在是将话题从测试切换到监控了吗？是也不是。

从历史上看，测试和监控是两种截然不同的学科。开发人员、测试人员和 QA 工程师关心的是孤立的工作功能。另一方面，平台和网站可靠性工程师关心的是一个工作正常且性能良好的生产环境。

不幸的是，直到今天，这些团队独立工作的现象也很常见。开发人员将新功能抛给基础架构人员，让他们想办法让它们继续运行。但为什么呢？

首先，是因为这些团队依赖于不同的工具。当测试和监控工具不同时，您应该如何协作？这对各方都具有挑战性，会减慢开发速度并阻碍协作。

正如解决方案工程师 Jonathan Canales 所描述的解决方案，一个统一的工具链可以实现快速迭代、高效测试和无缝监控。阿门！

但是，您如何统一测试和监控，甚至可以将所有测试重新用于合成监控？好吧……您可能应该采用“Monitoring as Code”。它使您可以测试部署，然后将测试重新用于 24/7 全球监控。这种方法确保您的用户在使用您的产品时获得愉快的体验。如果他们没有，您将是第一个了解生产问题的人。

### 结论

那么，现在是 API 测试更好还是 UI 测试更好？令人不快的答案是：都不是。两者都很重要！

要测试什么（以及何时测试）取决于您自己。您最了解您的产品及其关键任务型功能。只有您知道哪些功能不能被破坏。维护自动化测试可能是一项艰苦的工作，但易于实现并不是决定应该追求什么的衡量标准。

自动化测试不是关于您或使其工作所需的精力。自动化测试是关于在不破坏事物的情况下发布伟大功能。它是关于让您的客户满意 - 这才是最重要的。

