AWS Community Day Hong Kong 2025 Recap

从测试视角重新思考无服务器应用程序工作流

Recap Series

阶段 1:需求

架构概览

  • 使用 AWS Lambda 和 Step Functions 的批处理工作流。
  • 三个状态按直线顺序排列。
  • 每个 Lambda 函数都有单元测试,但 Step Functions 工作流仍需手动测试。

测试目标

  • 实现 Step Functions 工作流测试自动化。
  • 确保输入值和输出值与预期值一致。
  • 使用 GitHub Actions 将测试集成到 CI/CD 流水线中。
  • 避免为了测试而部署到真实的 AWS 环境。

阶段 2:计划

工具与技术

  • Step Functions Local:用于在本地运行和测试 Step Functions。
  • GitHub Actions:用于 CI/CD 工作流自动化。
  • Localstack 或类似工具:用于在本地模拟 AWS Lambda。

GitHub Actions 工作流

  • 配置工作流,在推送或拉取请求时运行测试。
  • 使用 Step Functions Local Docker 镜像搭建本地测试环境。
  • 使用 Localstack 模拟 Lambda。
  • https://www.localstack.cloud/
  • 导入 Step Functions 定义,并在本地运行工作流。
  • 验证每个状态的输入值和输出值。

工作流步骤

  • [ 1 ] 启动容器:
  • 拉取并启动 Step Functions Local Docker 镜像。
  • 配置 Localstack 以模拟 Lambda。
  • [ 2 ] 导入 Step Functions 定义:
  • 将状态机定义导入本地环境。
  • [ 3 ] 运行工作流:
  • 使用本地端点触发 Step Functions 工作流。
  • [ 4 ] 验证结果:
  • 对照预期值检查输入值和输出值。
  • [ 5 ] 报告结果:
  • 生成报告或状态,说明测试成功或失败。

如何测试无服务器架构?

简介

  • 无服务器架构优势显著,能够快速向客户交付价值。
  • 这里关注的是测试视角,而不是系统性能或成本。

为什么需要测试?

  • 测试帮助我们理解、预测和控制系统行为。
  • 测试让我们能够识别并量化系统风险。
  • 编写测试有助于更深入地理解需求。
  • 测试确保结果可复现、可解释。
  • 测试的首要目标是减少未知风险。

测试类型

  • 单元测试:独立测试各个组件或函数。
  • 集成测试:测试组合后各组件之间的交互。
  • 逻辑测试:验证业务逻辑的正确性。
  • 工作流测试:测试流程或工作流的端到端过程。
  • API 测试:测试 API 的功能和可靠性。

建议

  • 了解不同测试类型及其用途和目标非常重要。
  • 理解这些测试类型有助于为无服务器架构设计有效的测试策略。

拆分处理,让测试更容易

要点

  • 易测试的单元:容易测试的单元也容易理解。
  • 系统清晰度:当系统由相互独立、可测试的单元组成时,它会自然呈现出执行什么操作、何时执行以及为何执行。
  • 避免复杂性:如果某项内容难以测试,往往意味着过多职责和逻辑集中在同一处。

示例对比

  • 欠佳的架构:单个 Lambda 函数既负责从其他服务器获取数据,又负责处理数据并将其存入 DynamoDB。
  • 合理的架构:为每项操作分别使用 Lambda 函数(获取数据,以及处理/存储数据)。

拆分的优势

  • 更容易单独测试每个部分。
  • 出现错误时,更容易准确定位问题。
  • 缩短从错误发生到识别并修复错误所需的时间。

通用原则

  • 拆分方法:拆分方法这一原则适用于不同的编程语言(例如 Python、Ruby、Go)。
  • 小单元:明确您所认为的小型可测试单元,并据此应用拆分原则。

系统设计中的测试视角

  • 识别薄弱环节:从测试视角来看,很容易识别薄弱环节,例如过多职责集中在同一处。
  • 缩短错误发现时间:高可测试性有助于缩短从错误发生到发现并修复错误的时间,类似于缩短开发周期。
  • 快速交付:高可测试性有助于更快地交付系统。

从测试视角构建无服务器架构时的关键考虑因素

  • 拆分处理:容易测试的单元也容易理解。拆分处理有助于识别薄弱环节并缩短错误发现时间。
  • 避免复杂性:将职责和逻辑集中在同一处会增加测试难度。应拆分处理,以简化测试和故障排查。
  • 高可测试性:有助于更快地交付系统并缩短开发周期。

最终目标

  • 工程师的最终目标是为用户交付价值。
  • 始终将用户价值放在心上,才能确保取得成功。
  • 鼓励通过讨论和协作分享见解,改进测试实践。