

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

# 使用 sam local invoke 进行测试简介
<a name="using-sam-cli-local-invoke"></a>

使用 AWS Serverless Application Model Command Line Interface (AWS SAMCLI) `sam local invoke` 子命令在本地启动对 AWS Lambda 函数的一次性调用。
+ 有关简介 AWS SAMCLI，请参阅 [那是什么 AWS SAMCLI？](what-is-sam-overview.md#what-is-sam-cli)
+ 有关 `sam local invoke` 命令选项的列表，请参阅 [sam local invoke](sam-cli-command-reference-sam-local-invoke.md)。
+ 有关在典型开发工作流程中使用 `sam local invoke` 的示例，请参阅[第 7 步：（可选）在本地测试应用程序](serverless-getting-started-hello-world.md#serverless-getting-started-hello-world-test)。

**注意**  
不建议在不受信任的代码中使用 SAM CLI 的本地调用功能。要与本地环境完全隔离，请直接在 Lambda 服务中执行代码。

**注意**  
`sam local invoke`支持具有自动检查点和重播功能的耐用功能。在本地调用耐久函数时，会自动管理执行状态。

## 先决条件
<a name="using-sam-cli-local-invoke-prerequisites"></a>

要使用 `sam local invoke`，请完成以下操作安装 AWS SAM CLI。
+ [AWS SAM 先决条件](prerequisites.md).
+ [安装 AWS SAM CLI](install-sam-cli.md).

我们建议您在使用 `sam local invoke` 之前初步了解以下主题：
+ [配置 AWS SAM CLI](using-sam-cli-configure.md).
+ [在中创建您的应用程序 AWS SAM](using-sam-cli-init.md).
+ [搭建简介 AWS SAM](using-sam-cli-build.md).
+ [使用部署简介 AWS SAM](using-sam-cli-deploy.md).

## 本地调用 Lambda 函数
<a name="using-sam-cli-local-invoke-use"></a>

当您运行 `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>
   ```

1. 如果应用程序包含多个函数，请提供函数的逻辑 ID。以下是示例：

   ```
   $ sam local invoke HelloWorldFunction
   ```

1.  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\"}"}%
   ```

### 管理日志
<a name="using-sam-cli-local-invoke-logs"></a>

使用 `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
```

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

## 选项
<a name="using-sam-cli-local-invoke-options"></a>

### 传递自定义事件以调用 Lambda 函数
<a name="using-sam-cli-local-invoke-options-events"></a>

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

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

您可以使用 `sam local generate-event` 子命令创建事件。要了解更多信息，请参阅[使用 sam local generate-event 进行测试简介](using-sam-cli-local-generate-event.md)。

### 在调用 Lambda 函数时传递环境变量
<a name="using-sam-cli-local-invoke-options-env"></a>

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

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

### 指定模板或函数
<a name="using-sam-cli-local-invoke-options-specify"></a>

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

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

```
$ sam local invoke StackLogicalId/FunctionLogicalId
```

### 测试 Terraform 项目中的 Lambda 函数
<a name="using-sam-cli-local-invoke-options-terraform"></a>

使用 `--hook-name` 选项在本地测试 Terraform 项目中的 Lambda 函数。要了解更多信息，请参阅[使用 AWS SAM CLI 和 Terraform 进行本地调试和测试](using-samcli-terraform.md)。

以下是示例：

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

## 最佳实践
<a name="using-sam-cli-local-invoke-best"></a>

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

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

## 示例
<a name="using-sam-cli-local-invoke-examples"></a>

### 生成 Amazon API Gateway 示例事件并使用该事件在本地调用 Lambda 函数
<a name="using-sam-cli-local-invoke-examples-api"></a>

首先，生成 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 函数时传递环境变量
<a name="using-sam-cli-local-invoke-examples-env"></a>

此应用程序有一个 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":"{}"}
```

## 了解详情
<a name="using-sam-cli-local-invoke-learn"></a>

有关全部 `sam local invoke` 选项的列表，请参阅 [sam local invoke](sam-cli-command-reference-sam-local-invoke.md)。

有关使用 `sam local` 的演示，请参阅[用于本地开发的AWS SAM 。在 SA *M 系列开启的 Serverless Land Sessions 中测试来自本地开发环境的 AWS 云 *资源](https://www.youtube.com/watch?v=NzPqMrdgD1s&list=PLJo-rJlep0ED198FJnTzhIB5Aut_1vDAd&index=24)。YouTube