vlambda博客
学习文章列表

[译] 测试 Serverless 应用的最佳方法

原文:The best ways to test your serverless applications

Serverless(无服务器)不仅仅是云计算执行模型。它改变了我们设计,构建和部署应用的方式,也改变了我们测试应用的方式。

Alex 是一位普通的 JavaScript 开发人员,最近专注于 Node.js。我们通过他来了解 Serverless 应用是如何进行测试的。

T his is Alex

在过去的几个月中,他的好朋友 Anna 和 Jeff 一直在谈论 Serverless 的问题。尽管这有时候让 Alex 感到非常烦人,但他也喜欢使用 Serverless 开发的想法。有时候,他也会向 AWS Lambda 和 Azure 部署一些简单的功能。

[译] 测试 Serverless 应用的最佳方法

Anna and Jeff are always talking about that serverless thingy

有一天,Alex 和他的团队要着手开发一个新项目。经过分析,Alex 认为这个项目非常适合用 Serverless 开发,于是他向团队提出了他的想法。一些团队成员很兴奋,其中一个人不喜欢它,但是大多数人对此没有强烈的意见。因此,他们决定尝试一下——毕竟该项目规模不大,风险也很低。

[译] 测试 Serverless 应用的最佳方法

Alex 的团队讨论在新项目中使用 Serverless

团队阅读了 Serverless 的相关内容,他们了解了如何使用 Serverless 构建应用。但是没有人知道他们应该如何将 Serverless 应用到他们的开发流程中。

最后,他们定下来的开发流程是这样子的:

  1. 先对需求进行分析。
  2. 对于不太复杂的功能,他们先写代码,本地运行、跑通,最后添加测试用例。
  3. 对于比较复杂的功能,他们使用 TDD 模式开发:先写测试用例,再进行开发,然后在本地对其进行测试。
  4. 功能就绪后,将转到将其部署到测试环境的 CI 工具。
  5. 然后,质量检查小组将一项新功能用于另一轮手动测试。如果一切看起来不错,则该应用将通过 CI 进行生产。

[译] 测试 Serverless 应用的最佳方法

Alex 团队的开发流程

他们决定逐步开始,一步步解决遇到的问题。

他们挑了一个简单又小的功能点进行开发。然而当他们开发完成时,他们遇到了第一个问题:如何在本地运行 Serverless 应用?

本地调试

使用 Serverless 开发的应用,可以无需管理基础架构。但是要在本地运行该应用,这要怎么做呢?

[译] 测试 Serverless 应用的最佳方法

第一个障碍:如何在本地运行Serverless 应用?

根据自己的应用和选择的 Serverless 供应商,您可以在本地运行某些功能点。为此,您可以使用以下一些工具和技术:

  • Azure Functions Core Tools  (用于 Azure 云函数)
  • AWS SAM CLI (适用于使用 AWS SAM 构建的 AWS Lambda 应用程序)
  • 第三方工具 (比如:localstack )
  • 用于AWS Lambda本地模拟的 docker-lambda;
  • 在本地运行 Node.js 函数;

当然,这份清单并不完整 —— 实际上有更多工具,而且我们几乎每天都能看到新工具。

这些工具大多数都有一定的局限性。他们可以模拟 Serverless 云函数和其他一些服务,例如 API 网关。但是权限,身份验证层和其他服务呢?

我们可以在本地对这些函数进行测试,这有助于快速验证,以确保功能能够正常运行。但有没有更好的方法来确保 Serverless 应用能够按期运行?答案是有的。第一步也是最重要的一步是:编写测试。

最后,Alex 和他的团队在本地完成了他们的第一个功能,并且很顺利。然后他们决定进行下一步。

自动化测试

Alex 和他的团队刚刚切换到 Jest 来测试他们的 Node.js 应用。他们同时也做很多前端工作,因此他们希望在可能的情况下对整个项目使用相同的技术栈。他们也可以使用 Jest 测试 Serverless 应用吗?他们应该测试什么?

[译] 测试 Serverless 应用的最佳方法

第二个障碍:Serverless 对自动化测试有什么影响?

经过快速调查,他们发现可以使用自己喜欢的 Node.js 测试工具。Jest,Jasmine,Mocha 和其他服务器在 Serverless 下可以正常工作。

您应该在Serverless 应用中测试什么?

在测试他们的 Node.js 应用时,Alex 和他的团队遵循三层测试自动化金字塔。迈克·科恩(Mike Cohn)在他的书《Succeeding with Agile》 中首次提到了测试金字塔。

正如测试金字塔所定义的,它们具有:

  • 很多单元测试,因为它们成本最小(编写和运行最快)
  • 集成测试更少,它们昂贵一些,并且运行时间更长
  • 一些UI测试,因为它们是最昂贵的(需要一些GUI工具)并且运行最慢

除此之外,他们还具有由质量检查小组进行的基于会话的手动测试。

[译] 测试 Serverless 应用的最佳方法

算上人力成本的测试金字塔

那么 Serverless 是如何影响自动化测试金字塔?答案取决于金字塔的层级。但是测试金字塔看起来不太像埃及金字塔,更像玛雅金字塔。

单元测试层影响不大。单元测试仍然是编写和运行最便宜的方法,但是单元可以更小。

集成测试层比以往更加重要,因为 Serverless 应用严重依赖集成。它也更便宜,因为拥有仅用于测试的 Serverless 数据库很便宜。因此,在 Serverless 的“测试金字塔”中,需要进行更多的集成测试。

由于并行化便宜,GUI 测试层也越来越便宜。

手动测试层保持不变。但是 Serverless 可以进行一些改进。稍后我们将详细介绍。

[译] 测试 Serverless 应用的最佳方法

Serverless 的测试金字塔

现在 Alex 和他的团队终于能集中精力解决问题了。下一个问题是如何编写函数来更轻松地对其进行测试。

如何编写可测试的 Serverless 函数

编写 Serverless 函数时,需要考虑以下风险:

  • 配置风险:数据库和表是否正确,或者是否具有相应的访问权限?
  • 技术工作流程风险 是否做到按需解析和使用 Serverless 函数的请求?或者,您是否正确处理成功的响应和错误?
  • 业务逻辑风险 是否遵循应用具有的所有业务逻辑规则?
  • 集成风险 是否正确理解传入的请求结构?或者是否将订单正确存储到数据库中?

为了确认 Serverless 函数是否正常运行,你需要测试所有这些风险。

您可以像对集成测试一样对它们中的每一个进行测试。但是,每次要测试其中一种风险时,设置和配置服务都不是最佳选择。正如我的朋友 Aleksandar Simovic 喜欢说的:

试想一下,是否要以这种方式测试汽车。这意味着每次您要测试汽车中的单个螺钉甚至镜子时,都必须组装然后拆卸整个汽车。

为了使该应用更具测试性,明确的解决方案是将功能分解为几个比较小的功能点。一种很好的方法是将六角架构(Hexagonal Architecture)应用于 Serverless 函数。

六角体系结构(即「端口」和「适配器」)是一种应用体系结构,它通过职责层促进关注点的分离。创建者Alistair Cockburn 解释说:

用户,程序,自动测试或批处理脚本都可以运行程序,表现应该是一致的,并与最终的运行时设备和数据库隔离地进行开发和测试。

那么,这如何适用于 Serverless 函数呢?

Alex 和他的团队通过使用 AWS,最终得到了如下结构:

  • 函数业务逻辑只公开很少的「端口」(或期望很少的参数)。举个例子,一个用于传入事件,一个用于永久存储,另一个用于通知。
  • 他们有两个用于事件触发函数的适配器,一个用于真实的 AWS Lambda 触发器,另一个用于本地测试。
  • 他们有几个用于永久存储和通知的适配器。例如 DynamoDB 表适配器和内存适配器。

[译] 测试 Serverless 应用的最佳方法

AWS Lambda 功能的六边形架构

译者注:有关 AWS Lambda 更多的了解可以参考:AWS Lambda 功能

Alex 和他的团队为前进感到高兴。但是在讲解下一步之前,我们先看看六角结构如何影响测试金字塔的每一层。

Unit testing 单元测试

单元测试保持不变。但是由于采用了六角架构,因此编写单元测试更加容易。他们可以简单地使用本地适配器或通过模拟一个适配器来单独测试功能业务层。

Integration testing 集成测试

集成测试在六角结构中受益匪浅,因为他们能够自己完全做到集成测试。第三方集成是与其他适配器一起模拟的。

How does that work in practice? 在实践中又是如何处理的?

他们的每个Serverless 函数都有 /lambda.js/ 和 /main.js/ 文件。主文件包含Serverless 函数的业务逻辑。而 /lambda.js/ 文件负责接线适配器和调用的 /main.js/ 文件。

主文件有自己的单元和集成测试,但是主文件的集成测试不会测试与最终服务的完全集成(例如AWS S3),因为这会降低它们的处理速度。相反,他们使用内存中适配器通过文件存储集成来测试功能。

AWS S3 集成通过文件仓库(FileRepository)完成,该文件具有自己的单元和集成测试。集成测试检查使用 AWS S3 来确保最终集成确实有效。

与 /main.js/ 相对的,/lambda.js/ 文件没有测试,因为在大多数情况下,它只有几行代码。

[译] 测试 Serverless 应用的最佳方法

带有测试的单个AWS Lambda函数的可视化表示

这种方法类似于 MindMup 团队用于测试Serverless 函数的技术。有了它,您可以轻松地测试功能的集成,并且仍然可以使集成测试更快。

GUI testing GUI 测试

由于 Alex 和他的团队正在为该应用构建后端,因此 GUI 测试层并不重要。但是,随着他们对 Serverless 的了解越来越多,他们意识到可以使用它来改善他们正在使用的其他应用的 GUI 测试层。

UI 测试既昂贵又缓慢,因为它们在浏览器中运行。但是, Serverless 很便宜,而且可以快速扩展。

如果他们可以在 AWS Lambda 中运行浏览器,那么它们的并行化成本会小很多。这将使他们的 UI 测试更加便宜和快捷。

但是,您可以在 Serverless 函数内运行浏览器(例如 Chrome)吗?

答案是:可以! 借助 Serverless Chrome,Chromeless 和 Puppeteer 之类的工具,可以很容易实现上面的功能。

[译] 测试 Serverless 应用的最佳方法

使用 AWS Lambda 函数进行 UI 测试的并行化

无服务器浏览器和无头浏览器的组合可以为我们带来新一代的 UI 测试工具。我们已经可以看到并尝试其中的一些方法,例如 Appraise。

CI / CD

当 Alex 和他的团队测试他们的第一个 Serverless 函数时,就需要将代码部署到测试环境了。这就提出了一个新问题:他们如何使用CI / CD工具来部署其 Serverless 应用?

[译] 测试 Serverless 应用的最佳方法

答案很简单:他们可以使用 CI 工具来运行测试和部署应用程序。要部署该应用,可以使用任何流行的工具,例如 Claudia.js ,AWS SAM和 Serverless Framework。

您仍然可以使用自己喜欢的 CI 工具(例如 Jenkins,TravisCI 或 SemaphoreCI),或者,如果要坚持使用 AWS,则可以尝试 AWS CodeBuild。

Manual testing 手动测试

即使手动测试不受 Serverless 的直接影响,Alex 的团队也找到了改进其质量检查流程的方法。

[译] 测试 Serverless 应用的最佳方法

Serverless 应用的阶段和部署很便宜,并且通常可以快速设置。此外,使用 Serverless,如果没有人使用它,则无需为该应用付费。

这意味着拥有测试环境非常便宜!

你可以经常推动函数从一个阶段更新到另一个阶段。这意味着您的质量检查团队可以测试一项功能,当他们确认该功能有效时,您可以将该功能推广到生产中。

Beyond testing 不止于测试

Alex 和他的团队将其第一个 Serverless 函数部署到了预生产环境中,并且团队很高兴他们学会了如何测试 Serverless 应用。

[译] 测试 Serverless 应用的最佳方法

他们继续在该项目上使用 Serverless,并推广给其他几个项目。Alex 加入了他的朋友 Anna 和Jeff,成为第三位 Serverless 的传教士(虽然有时候会让其他人反感)。从此他们过着幸福的生活。

Serverless 的传教士团队有了新成员

Post-script 后记

虽然 Alex 他们的应用经过了严格的测试,但还是发生了一些意外。

经过调查,他们发现其中一个集成发生了变化。他们了解到测试对 Serverless 应用很重要,但这还不够。

由于 Serverless 应用严重依赖集成,因此风险从代码转移到集成。而且,为了能够捕获集成更改并快速做出反应,应用程序需要适当的监控。

幸运的是,每天市场上都有越来越多的 Serverless 监视工具。IOpipe,Thundra ,  Dashbird,Dashbird 和 Epsagon 是一些不错的受欢迎的选择。

但是,Serverless 应用通常是大型的客户端系统,这意味着后端监视还不够。您的前端需要类似的工具。这个市场也有很多不错的工具,例如 Sentry 和Rollbar。

为了弘扬 Serverless 的精神,我们创建了一个名为 Desole 的开源错误跟踪应用程序。这是一个 Serverless 应用,您可以在您的 AWS 账户中安装。它使组织能够跟踪应用程序异常和错误,而不必在软件即服务的便捷性和自托管解决方案的安全性之间进行选择。关于更多可以在这里查看:https://desole.io。

Desole, open source error-tracking, tightly integrated with AWS

如果想了解有关使用 Node.js 和 AWS 测试和构建Serverless 应用的更多信息,请查看作者与 Aleksandar Simovic 为 Manning Publications 撰写的书 Serverless Applications with Node.js 。

该书将通过代码示例向您介绍有关 Serverless 测试的更多信息,您还将学习如何使用 Node 和Claudia.js 构建和调试真实的 Serverless API(具有数据库和身份验证)。您还将学习如何为 Facebook Messenger 和 SMS(使用 Twilio)以及 Alexa 技能构建聊天机器人。

所有插图都是使用 SimpleDiagrams4 应用程序创建的。