亚马逊AWS官方博客

利用 AWS Step Functions 中增强的本地测试功能加快工作流开发速度



今天,我很高兴地宣布,我们通过 TestState API(我们的测试 API)增强了 AWS Step Functions 的本地测试功能。

这些增强功能可通过 API 使用,因此您可以构建自动化测试套件,在本地开发机器上验证工作流定义、测试错误处理模式、数据转换,并使用您首选的测试框架模拟服务集成。此次发布引入了一种基于 API 的本地单元测试方法,无需部署到 Amazon Web Services(AWS)即可通过编程方式访问全面的测试功能。

此增强版 TestState API 引入了三项关键功能:

  • 模拟支持 – 无需调用下游服务即可模拟状态输出和错误,从而实现对状态机逻辑的真正单元测试。TestState 根据 AWS API 模型来验证模拟响应,提供三种验证模式:STRICT(默认模式,验证所有必填字段)、PRESENT(验证字段类型和名称)和 NONE(无验证),确保测试的高保真度。

  • 支持所有状态类型 — 现在可以测试所有状态类型,包括高级状态,如 Map 状态(内联式和分布式)、Parallel 状态、基于活动的 Task 状态、.sync 服务集成模式以及 .waitForTaskToken 服务集成模式。这意味着您可以在整个工作流定义中使用 TestState API,并编写单元测试来验证控制流逻辑,包括状态转换、错误处理和数据转换。

  • 测试单个状态 — 使用新的 stateName 参数测试完整状态机定义中的特定状态。您可以一次性提供完整的状态机定义,然后按名称单独测试每个状态。您可以控制执行上下文来测试特定的重试尝试、Map 迭代位置和错误场景。

增强版 TestState 入门
接下来,我将带您了解增强版 TestState 的这些新功能。

场景 1:模拟成功结果

第一个功能是模拟支持,您可以使用它来测试工作流逻辑,而无需调用实际的 AWS 服务,甚至无需发送外部 HTTP 请求。您可以模拟服务响应以进行快速单元测试,也可以使用实际的 AWS 服务进行集成测试。使用模拟响应时,无需 AWS Identity and Access Management(IAM)权限。

以下是模拟 AWS Lambda 函数成功响应的方法:

aws stepfunctions test-state --region us-east-1 \
--definition '{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {"FunctionName": "process-order"},
  "End": true
}' \
--mock '{"result":"{\"orderId\":\"12345\",\"status\":\"processed\"}"}' \
--inspection-level DEBUG

该命令可在不真正调用函数的情况下测试 Lambda 调用状态。TestState 会根据 Lambda 服务 API 模型验证您的模拟响应,确保测试数据与真实服务的返回格式一致。

响应结果会显示执行成功,并包含详细的检查数据(使用 DEBUG 检查级别时):

{
    "output": "{\"orderId\":\"12345\",\"status\":\"processed\"}",
    "inspectionData": {
        "input": "{}",
        "afterInputPath": "{}",
        "afterParameters": "{\"FunctionName\":\"process-order\"}",
        "result": "{\"orderId\":\"12345\",\"status\":\"processed\"}",
        "afterResultSelector": "{\"orderId\":\"12345\",\"status\":\"processed\"}",
        "afterResultPath": "{\"orderId\":\"12345\",\"status\":\"processed\"}"
    },
    "status": "SUCCEEDED"
}

当您指定模拟响应时,TestState 会根据 AWS 服务的 API 模型对其进行验证,以确保您的模拟数据符合预期模式,从而在无需真正调用 AWS 服务的情况下保持高保真测试。

场景 2:模拟错误情况
您也可以模拟错误情况来测试错误处理逻辑:

aws stepfunctions test-state --region us-east-1 \
--definition '{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {"FunctionName": "process-order"},
  "End": true
}' \
--mock '{"errorOutput":{"error":"Lambda.ServiceException","cause":"Function failed"}}' \
--inspection-level DEBUG

此命令模拟 Lambda 服务异常,让您能够验证状态机如何处理故障,而不在 AWS 环境中触发实际错误。

响应显示执行失败及其错误详情:

{
    "error": "Lambda.ServiceException",
    "cause": "Function failed",
    "inspectionData": {
        "input": "{}",
        "afterInputPath": "{}",
        "afterParameters": "{\"FunctionName\":\"process-order\"}"
    },
    "status": "FAILED"
}

场景 3:测试 Map 状态
第二项功能新增了对之前不支持的状态类型的支持。以下是测试分布式 Map 状态的方法:

aws stepfunctions test-state --region us-east-1 \
--definition '{
  "Type": "Map",
  "ItemProcessor": {
    "ProcessorConfig": {"Mode": "DISTRIBUTED", "ExecutionType": "STANDARD"},
    "StartAt": "ProcessItem",
    "States": {
      "ProcessItem": {
        "Type": "Task",
        "Resource": "arn:aws:states:::lambda:invoke",
        "Parameters": {"FunctionName": "process-item"},
        "End": true
      }
    }
  },
  "End": true
}' \
--input '[{"itemId":1},{"itemId":2}]' \
--mock '{"result":"[{\"itemId\":1,\"status\":\"processed\"},{\"itemId\":2,\"status\":\"processed\"}]"}' \
--inspection-level DEBUG

模拟结果代表处理多个项目后的完整输出。在这种情况下,模拟数组必须与预期的 Map 状态输出格式匹配。

响应显示数组输入已成功处理:

{
    "output": "[{\"itemId\":1,\"status\":\"processed\"},{\"itemId\":2,\"status\":\"processed\"}]",
    "inspectionData": {
        "input": "[{\"itemId\":1},{\"itemId\":2}]",
        "afterInputPath": "[{\"itemId\":1},{\"itemId\":2}]",
        "afterResultSelector": "[{\"itemId\":1,\"status\":\"processed\"},{\"itemId\":2,\"status\":\"processed\"}]",
        "afterResultPath": "[{\"itemId\":1,\"status\":\"processed\"},{\"itemId\":2,\"status\":\"processed\"}]"
    },
    "status": "SUCCEEDED"
}

场景 4:测试 Parallel 状态
同样,您可以测试并发执行多个分支的 Parallel 状态:

aws stepfunctions test-state --region us-east-1 \
--definition '{
  "Type": "Parallel",
  "Branches": [
    {"StartAt": "Branch1", "States": {"Branch1": {"Type": "Pass", "End": true}}},
    {"StartAt": "Branch2", "States": {"Branch2": {"Type": "Pass", "End": true}}}
  ],
  "End": true
}' \
--mock '{"result":"[{\"branch1\":\"data1\"},{\"branch2\":\"data2\"}]"}' \
--inspection-level DEBUG

模拟结果必须是一个数组,每个分支对应一个元素。通过 TestState,您的模拟数据结构将与真实 Parallel 状态执行的输出匹配。

响应会显示并行执行的结果:

{
    "output": "[{\"branch1\":\"data1\"},{\"branch2\":\"data2\"}]",
    "inspectionData": {
        "input": "{}",
        "afterResultSelector": "[{\"branch1\":\"data1\"},{\"branch2\":\"data2\"}]",
        "afterResultPath": "[{\"branch1\":\"data1\"},{\"branch2\":\"data2\"}]"
    },
    "status": "SUCCEEDED"
}

场景 5:测试完整工作流中的单个状态
您可以使用 stateName 参数测试完整状态机定义中的特定状态。以下示例展示了如何测试单个状态,但您通常会提供完整的工作流定义,并指定要测试的状态:

aws stepfunctions test-state --region us-east-1 \
--definition '{
  "Type": "Task",
  "Resource": "arn:aws:states:::lambda:invoke",
  "Parameters": {"FunctionName": "validate-order"},
  "End": true
}' \
--input '{"orderId":"12345","amount":99.99}' \
--mock '{"result":"{\"orderId\":\"12345\",\"validated\":true}"}' \
--inspection-level DEBUG

此命令使用特定的输入数据测试 Lambda 调用状态,显示 TestState 如何处理输入并在状态执行过程中进行转换。

响应显示了详细的输入处理和验证过程:

{
    "output": "{\"orderId\":\"12345\",\"validated\":true}",
    "inspectionData": {
        "input": "{\"orderId\":\"12345\",\"amount\":99.99}",
        "afterInputPath": "{\"orderId\":\"12345\",\"amount\":99.99}",
        "afterParameters": "{\"FunctionName\":\"validate-order\"}",
        "result": "{\"orderId\":\"12345\",\"validated\":true}",
        "afterResultSelector": "{\"orderId\":\"12345\",\"validated\":true}",
        "afterResultPath": "{\"orderId\":\"12345\",\"validated\":true}"
    },
    "status": "SUCCEEDED"
}

这些增强功能为 Step Functions 工作流带来了熟悉的本地开发体验,帮助我在部署到 AWS 账户之前,快速获得变更反馈。我可以编写自动化测试套件,以与云执行相同的可靠性验证所有 Step Functions 特征,从而确保我的工作流在部署后能够按预期运行。

注意事项
以下是需要注意的要点:

  • 可用性 — 增强的 TestState 功能在所有支持 Step Functions 的 AWS 区域均可用。
  • 定价 — TestState API 调用包含在 AWS Step Functions 中,无需另行付费。
  • 框架兼容性 — TestState 可与任何能够发出 HTTP 请求的测试框架配合使用,包括 Jest、pytest、JUnit 等。您可以在部署之前,在持续集成和持续交付(CI/CD)管道中编写测试套件,以自动验证您的工作流。
  • 特征支持 — 增强版 TestState 支持所有 Step Functions 特征,包括分布式 Map、Parallel 状态、错误处理和 JSONata 表达式。
  • 文档 — 有关不同配置的详细选项,请参阅 TestState 文档API 参考,了解更新后的请求和响应模型。

立即将 TestState 集成到您的开发工作流程中,开始体验更强大的本地测试功能。

祝您构建顺利!
Donnie

AWS 架构师中心: 云端创新的引领者

探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用