使用 sam local invoke 进行测试简介 - AWS Serverless Application Model

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用 sam local invoke 进行测试简介

使用 AWS Serverless Application Model 命令行界面 (AWS SAM CLI) sam local invoke 子命令在本地启动 AWS Lambda 函数的一次性调用。

要使用 sam local invoke,请完成以下操作安装 AWS SAM CLI。

我们建议您在使用 sam local invoke 之前初步了解以下主题:

本地调用 Lambda 函数

当您运行 sam local invoke 时,AWS SAM CLI 会假设当前工作目录是项目的根目录。AWS SAM CLI 会首先在 .aws-sam 子文件夹中查找 template.[yaml|yml] 文件。如果找不到,AWS SAM CLI 会在当前工作目录中查找 template.[yaml|yml] 文件。

在本地调用 Lambda 函数
  1. 从项目的根目录中,运行以下命令:

    $ sam local invoke <options>
  2. 如果应用程序包含多个函数,请提供函数的逻辑 ID。以下是示例:

    $ sam local invoke HelloWorldFunction
  3. AWS SAM CLI 会使用 Docker 在本地容器中构建函数。然后,它会调用函数并输出函数的响应。

    以下是示例:

    $ sam local invoke Invoking app.lambda_handler (python3.9) Local image is out of date and will be updated to the latest runtime. To skip this, pass in the parameter --skip-pull-image Building image.................................................................................................................... Using local image: public.ecr.aws/lambda/python:3.9-rapid-x86_64. Mounting /Users/.../sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container START RequestId: 64bf7e54-5509-4762-a97c-3d740498d3df Version: $LATEST END RequestId: 64bf7e54-5509-4762-a97c-3d740498d3df REPORT RequestId: 64bf7e54-5509-4762-a97c-3d740498d3df Init Duration: 1.09 ms Duration: 608.42 ms Billed Duration: 609 ms Memory Size: 128 MB Max Memory Used: 128 MB {"statusCode": 200, "body": "{\"message\": \"hello world\"}"}%

管理日志

使用 sam local invoke 时,Lambda 函数运行时输出(例如日志)会输出到 stderr,Lambda 函数结果会输出到 stdout

以下是基础 Lambda 函数的示例:

def handler(event, context): print("some log") # this goes to stderr return "hello world" # this goes to stdout

您可以保存这些标准输出。以下是示例:

$ sam local invoke 1> stdout.log ... $ cat stdout.log "hello world" $ sam local invoke 2> stderr.log ... $ cat stderr.log Invoking app.lambda_handler (python3.9) Local image is up-to-date Using local image: public.ecr.aws/lambda/python:3.9-rapid-x86_64. Mounting /Users/.../sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container START RequestId: 0b46e646-3bdf-4b58-8beb-242d00912c46 Version: $LATEST some log END RequestId: 0b46e646-3bdf-4b58-8beb-242d00912c46 REPORT RequestId: 0b46e646-3bdf-4b58-8beb-242d00912c46 Init Duration: 0.91 ms Duration: 589.19 ms Billed Duration: 590 ms Memory Size: 128 MB Max Memory Used: 128 MB

您可以使用这些标准输出来进一步自动化您的本地开发流程。

Options

传递自定义事件以调用 Lambda 函数

要将事件传递给 Lambda 函数,请使用 --event 选项。以下是示例:

$ sam local invoke --event events/s3.json S3JsonLoggerFunction

您可以使用 sam local generate-event 子命令创建事件。要了解更多信息,请参阅 使用测试简介 sam local generate-event

在调用 Lambda 函数时传递环境变量

如果 Lambda 函数使用环境变量,则您可以在本地测试期间使用 --env-vars 选项传递这些变量。这是使用已经部署在云中应用程序中的服务在本地测试 Lambda 函数的好方法。以下是示例:

$ sam local invoke --env-vars locals.json

指定模板或函数

要为 AWS SAM CLI 指定要引用的模板,请使用 --template 选项。AWS SAM CLI 只会加载该 AWS SAM 模板及其指向的资源。

要调用嵌套应用程序或堆栈的函数,请提供应用程序或堆栈的逻辑 ID 以及函数逻辑 ID。以下是示例:

$ sam local invoke StackLogicalId/FunctionLogicalId

测试 Terraform 项目中的 Lambda 函数

使用 --hook-name 选项在本地测试 Terraform 项目中的 Lambda 函数。要了解更多信息,请参阅 使用 AWS SAM CLI 替换为 Terraform 用于本地调试和测试

以下是示例:

$ sam local invoke --hook-name terraform --beta-features

最佳实践

如果应用程序有无法运行 sam build.aws-sam 目录,请务必在每次更新函数代码时都运行 sam build。然后,运行 sam local invoke,以在本地测试更新后的函数代码。

本地测试是部署到云中之前进行快速开发和测试的理想解决方案。但是,本地测试并不能验证所有内容,例如,不能验证云端资源之间的权限。尽可能在云端测试应用程序。我们建议使用 sam sync 来加快云测试工作流程。

示例

生成 Amazon API Gateway 示例事件并使用该事件在本地调用 Lambda 函数

首先,生成 API Gateway HTTP API 事件有效负载并将其保存到 events 文件夹中。

$ sam local generate-event apigateway http-api-proxy > events/apigateway_event.json

然后,修改 Lambda 函数以从事件中返回参数值。

def lambda_handler(event, context): print("HelloWorldFunction invoked") return { "statusCode": 200, "body": json.dumps({ "message": event['queryStringParameters']['parameter2'], }), }

然后,在本地调用 Lambda 函数并提供自定义事件。

$ sam local invoke --event events/apigateway_event.json Invoking app.lambda_handler (python3.9) Local image is up-to-date Using local image: public.ecr.aws/lambda/python:3.9-rapid-x86_64. Mounting /Users/...sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container START RequestId: 59535d0d-3d9e-493d-8c98-6264e8e961b8 Version: $LATEST some log END RequestId: 59535d0d-3d9e-493d-8c98-6264e8e961b8 REPORT RequestId: 59535d0d-3d9e-493d-8c98-6264e8e961b8 Init Duration: 1.63 ms Duration: 564.07 ms Billed Duration: 565 ms Memory Size: 128 MB Max Memory Used: 128 MB {"statusCode": 200, "body": "{\"message\": \"value\"}"}%

在本地调用 Lambda 函数时传递环境变量

此应用程序有一个 Lambda 函数,该函数使用环境变量作为 Amazon DynamoDB 表的名称。以下是 AWS SAM 模板中定义的函数示例:

AWSTemplateFormatVersion: 2010-09-09 Transform: AWS::Serverless-2016-10-31 ... Resources: getAllItemsFunction: Type: AWS::Serverless::Function Properties: Handler: src/get-all-items.getAllItemsHandler Description: get all items Policies: - DynamoDBReadPolicy: TableName: !Ref SampleTable Environment: Variables: SAMPLE_TABLE: !Ref SampleTable ...

我们要在本地测试 Lambda 函数,同时让它与云中的 DynamoDB 表进行交互。为此,我们创建环境变量文件,并将其保存在项目的根目录中,文件名为 locals.json。此处为SAMPLE_TABLE提供的值引用了云中的 DynamoDB 表。

{ "getAllItemsFunction": { "SAMPLE_TABLE": "dev-demo-SampleTable-1U991234LD5UM98" } }

然后,运行 sam local invoke,并使用 --env-vars 选项传入环境变量。

$ sam local invoke getAllItemsFunction --env-vars locals.json Mounting /Users/...sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated, inside runtime container START RequestId: 59535d0d-3d9e-493d-8c98-6264e8e961b8 Version: $LATEST some log END RequestId: 59535d0d-3d9e-493d-8c98-6264e8e961b8 REPORT RequestId: 59535d0d-3d9e-493d-8c98-6264e8e961b8 Init Duration: 1.63 ms Duration: 564.07 ms Billed Duration: 565 ms Memory Size: 128 MB Max Memory Used: 128 MB {"statusCode":200,"body":"{}"}

了解更多

有关全部 sam local invoke 选项的列表,请参阅 sam local invoke

有关使用 sam local 的演示,请参阅用于本地开发的 AWS SAM。YouTube 上 Serverless Land“使用 SAM 的会话”系列中的测试本地开发环境中的 AWS Cloud 资源