AWS Lambda 上的 .NET 工作负载

模块 5

模块 5:单元测试和调试

 学习模块

请注意,您可以按照此处提供的示例进行操作,但这不是强制要求。

有多种方法可以测试 Lambda 函数。最简单的方法是使用和构建 AWS Lambda 项目模板中提供的单元测试。运行测试只需要在 IDE 中使用熟悉的测试运行程序或简单的 dotnet 测试。

另一种选择是使用 AWS .NET Mock Lambda 测试工具。目前处于预览状态。这使您可以测试和调试您的 Lambda 函数。该工具包含于 Visual Studio 的 AWS Toolkit,作为其中一部分。但是您可以下载它,以便在命令行、VS Code 和 Rider 中使用。

如果您正在开发部署到容器的 Lambda 函数,则 Runtime Interface Emulator 将让您测试在容器内运行的函数。

您可以使用诸如 localstack 之类的第三方工具在本地测试您的函数,但是执行函数测试的最佳方法是将您的 Lambda 函数部署到 AWS 并在那里进行测试。AWS 每月为所有账户提供 100 万次免费请求;每月最多提供 320 万秒的计算时间。因此,几乎没有理由不在 AWS Cloud 上测试您的函数。

有关定价的更多信息,请参阅以下两个页面 – 开始使用 AWS Free Tier、AWS Lambda 定价。

使用这些本地测试工具,也可以轻松进行一些调试。稍后将展示一个简单示例。

 所需时间

30 分钟 

xUnit 测试项目

许多 .NET Lambda 函数项目模板都包含 xUnit 测试项目。不做任何更改,您就可以在这个项目中执行测试,且会通过测试。
使用以下方法创建一个新 Lambda 函数:
dotnet new lambda.EmptyFunction -n FunctionWithTestProject
变更为 FunctionWithTestProject/test/FunctionWithTestProject.Tests 目录:
cd FunctionWithTestProject/test/FunctionWithTestProject.Tests
在 IDE 中打开该项目。

打开 FunctionWithTestProject.Tests.csproj 文件,您将看到一个 Lambda 函数项目的项目引用。
<ProjectReference Include="..\..\src\FunctionWithTestProject\FunctionWithTestProject.csproj" />

在命令行中,使用以下命令运行测试:

dotnet test
您将看到如下所示的输出:
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.

Passed!  - Failed:     0, Passed:     1, Skipped:     0, Total:     1, Duration: < 1 ms - FunctionWithTestProject.Tests.dll (net6.0)
当然,您可以在 Visual Studio、VS Code 或 Rider 中打开测试项目,然后从那里执行测试。

在 Visual Studio 中,转到“测试”菜单,然后选择“运行所有测试”。这还将打开“测试资源管理器”,您将在其中看到测试结果。
在 Rider 中,前往“测试”菜单,然后选择“运行解决方案中的所有测试”。这将运行测试并打开“单元测试”窗口,您将在其中看到结果。
对于 VS Code,您可以轻松运行单个测试或文件中的所有测试
但是,如果您的测试在多个文件中,您将需要一个测试运行器扩展名。请查看扩展程序的文档,了解更多信息或配置和运行测试。

当您更改函数中的代码时,您可以像更新普通测试项目一样更新测试。因为这是一个测试项目,就像您编写的任何其他项目一样,您可以使用相同的库来帮助自己,比如 moq。

AWS .NET Mock Lambda 测试工具

此工具允许您使用自己定义的负载在本地调用 Lambda 函数并检验响应。

如上所述,如果您在 Visual Studio 中使用 AWS Toolkit,则该工具已包含在内。

您可以在 Visual Studio、VS Code、Rider 或命令行中使用该工具。

命令行允许您在两种模式下运行:

1.使用基于 Web 浏览器的用户界面

2.没有用户界面

接下来的几步操作演示了如何通过命令行使用该工具,但如果您愿意,可以随时跳到有关 Visual Studio 的部分。

安装该工具

对于命令行、VS Code 和 Rider,您需要安装该工具。

从命令行运行:
dotnet tool install -g Amazon.Lambda.TestTool-6.0
如果您已安装该工具,请使用以下方法对其进行更新:
dotnet tool update -g Amazon.Lambda.TestTool-6.0

命令行测试

使用上面的示例项目,从命令行导航到 FunctionWithTestProject/src/FunctionWithTestProject 目录。

要从命令行运行测试,您必须指定 --no-ui 选项,然后输入负载。负载的逃逸有所不同,这取决于您所使用的 shell。以下内容适用于 PowerShell。

从命令行运行:
dotnet lambda-test-tool-6.0 --no-ui --payload '\"hello\"'
用于 bash 用途:
dotnet lambda-test-tool-6.0 --no-ui --payload '"hello"'
您应看到如下输出:
AWS .NET Core 6.0 Mock Lambda Test Tool (0.12.3)
Loaded local Lambda runtime from project output C:\dev\FunctionWithTestProject\src\FunctionWithTestProject\bin/Debug/net6.0
Executing Lambda function without web interface
Found Lambda config file C:\dev\FunctionWithTestProject\src\FunctionWithTestProject\aws-lambda-tools-defaults.json
... Using config file C:\dev\FunctionWithTestProject\src\FunctionWithTestProject\aws-lambda-tools-defaults.json
... Using function handler FunctionWithTestProject::FunctionWithTestProject.Function::FunctionHandler
... Using payload with the value "hello"
... Setting AWS_PROFILE environment variable to default.
... No default AWS region configured. The --region switch can be used to configure an AWS Region.
Captured Log information:    

Request executed successfully
Response:
"HELLO"
Press any key to exit 
在响应部分,您可以看到 Lambda 函数的输出。

Web UI 测试,从命令行启动

您也可以使用命令行中的工具来启动 Web UI 进行测试。

在用户界面中,您可以输入自己的负载,但在这种情况下您不必担心逃逸。或者,您可以从一组示例请求负载中进行选择。这些负载允许您模拟来自其他 AWS 服务的请求,例如 S3、Kinesis、SQS 等。

但是现在,输入 "hello"(包括引号)作为负载,然后按下“执行函数”按钮。

在响应部分,您将看到函数返回值。

如果您在函数中添加了日志语句,则会在“日志输出”部分看到这些语句。

Visual Studio

如果您安装了适用于 Visual Studio 的 AWS Toolkit,那么您已经安装了 AWS .NET Mock Lambda 测试工具。

在 Visual Studio 中打开 FunctionWithTestProject/src/FunctionWithTestProject 项目。

Visual Studio 将创建一个 Properties 目录,并在该目录中创建一个 launchsettings.json 文件,该文件将 AWS .NET Mock Lambda 测试工具连接到您的代码。

该文件将如下所示:
{
  "profiles": {
    "Mock Lambda Test Tool": {
      "commandName": "Executable",
      "commandLineArgs": "--port 5050",
      "workingDirectory": ".\\bin\\$(Configuration)\\net6.0",
      "executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-6.0.exe"
    }
  }
}
按 F5 启动应用程序。您在上面看到的同一页面将打开,输入您的负载并按下“执行函数”按钮。

VS Code

要使用 VS Code 中的 AWS .NET Mock Lambda 测试工具,请按照此处的说明进行操作 – https://github.com/aws/aws-lambda-dotnet/tree/master/Tools/LambdaTestTool#configure-for-visual-studio-code

注意:

1. 您应该将 dotnet-lambda-test-tool-3.1 改为 dotnet-lambda-testtool-6.0。

2. 如果您使用的是 Linux/Mac dotnet-lambda-test-tool-6.0 ,将没有 .exe 扩展名。

Rider

要为 Rider 配置 AWS .NET Mock Lambda 测试工具,请按照此处说明进行
操作 –

容器和 Runtime Interface Emulator

如果您要在容器内部署 Lambda 函数,则可以使用 AWS Runtime Interface Emulator(RIE)进行另一层本地测试。您无需安装任何新工具,这些工具将自动打包入您构建的容器中。

在此示例中,您将编写一个拥有两个函数处理程序的无服务器应用程序。

使用以下方法创建基于容器的新项目:

dotnet new serverless.image.EmptyServerless --name TestingFunctionWithRIE
该项目包含一个 Dockerfile。打开这个文件,您会看到 Docker 将文件从 bin/release/Lambda-publish 目录复制到 Docker 容器:
COPY "bin/Release/lambda-publish"  .
打开 Function.cs 文件并将 Get (...) 方法替换为以下方法:
public APIGatewayProxyResponse Get(APIGatewayProxyRequest request, ILambdaContext context)
{
    context.Logger.LogInformation($"Get method invoked. You requested {request.PathParameters["Id"]}");

    var response = new APIGatewayProxyResponse
    {
        StatusCode = (int)HttpStatusCode.OK,
        Body = $"You were looking for something with an Id of : {request.PathParameters["Id"]}",
      Headers = new Dictionary<string, string> {
        {
      "Content-Type",
      "application/json"
         }

        }
    };
            
    return response;
}
变更为 TestingFunctionWithRIE/src/TestingFunctionWithRIE 目录:
cd TestingFunctionWithRIE/src/TestingFunctionWithRIE 
运行以下命令:
dotnet build -c Release -o .\bin\Release\lambda-publish\ 
这将构建应用程序,并将二进制文件放在 .\bin\Release\lambda-publish 目录。

确保 Docker 正在运行,然后构建容器:
docker build -t testing_function_with_rie:latest .
完成后就启动容器:
docker run -it -p 9000:8080 testing_function_with_rie:latest TestingFunctionWithRIE::TestingFunctionWithRIE.Functions::Get
此命令启动 docker 容器并通过计算机上的端口 9000 暴露内部端口 8080,并将函数处理程序作为参数传递。Runtime Interface Emulator 使用它在您的应用程序中执行相应的方法。

如果您的代码中有多个函数处理程序,则应依次测试每个函数处理程序,启动容器并每次传递相应的函数处理程序。

最后,向 Runtime Interface Emulator 发出 HTTP 请求。您可以使用 Fiddler、Postman、Insomnia 等。以下是使用 VS Code Rest 客户端或 Rider Http 客户端发起的请求:
POST http://localhost:9000/2015-03-31/functions/function/invocations HTTP/1.1
content-type: application/json

{
    "PathParameters": {
        "Id": "999"
    }
}
您将看到如下响应:
HTTP/1.1 200 OK
Date: Fri, 29 Jul 2022 18:03:56 GMT
Content-Length: 148
Content-Type: text/plain; charset=utf-8
Connection: close

{
  "statusCode": 200,
  "headers": {
    "Content-Type": "application/json"
  },
  "body": "You were looking for something with an Id of : 999",
  "isBase64Encoded": false
}
如果您想更改代码并再次测试,请使用以下代码,它将 .NET 构建、容器构建和启动容器合并为一行:
dotnet build -c Release -o .\bin\Release\lambda-publish\ ; docker build -t testing_function_with_rie:latest . ; docker run -it -p 9000:8080 testing_function_with_rie:latest TestingFunctionWithRIE::TestingFunctionWithRIE.Functions::Get

在 AWS 上测试您的 Lambda 函数

上述工具非常适合在本地测试您的 Lambda 函数,尽管有一些工具可以帮助您应对模拟 AWS 环境,但测试函数的最佳方法是使用 AWS Lambda 服务。

AWS 提供丰富且始终免费的套餐,允许您每月免费执行一百万个 Lambda 请求,如果您超过该限制,接下来的 100 万次执行将花费 0.20 美元,即每次执行 0.0000002 美元。在定价方面有一些注意事项,与内存使用量和运行时间有关,请参阅 – 开始使用 AWS Free TierAWS Lambda 定价,了解更多信息。

尽管模拟器工具可能很好,如果您没有互联网连接,您可能会发现其效果与真正的 AWS 服务并不完全相同。在 AWS 中测试您的 Lambda 函数意味着部署代码时不会出现意外。

您所需要做的就是创建一个 .NET 测试项目,xUnit 模板是一个不错的选择。然后,针对您部署到 AWS 的 Lambda 函数编写函数测试。

dotnet new xunit -n LambdaTestProject

有关测试部署到 AWS 的 .NET Lambda 函数的演示,请参阅博客文章开发 .NET Core AWS Lambda 函数。

调试

您可能需要不时在本地调试您的 Lambda 函数。有两种简单的方法可以让您做到这一点:

1.在单元测试项目中放置一个断点,然后进入该函数。

2.从您的 IDE 中启动 AWS .NET Mock Lambda 测试工具,在函数中放置一个断点,然后通过测试工具执行该函数。

使用单元测试项目

在使用 Visual Studio、VS Code 和 Rider 时,同样的原则也适用。

打开测试项目并在代码中调用 Lambda 函数的地方放置一个断点。

调试测试。当您遇到断点时,进入 Lambda 函数。
现在,您将进入您的 Lambda 函数代码!


使用 AWS .NET Mock Lambda 测试工具

这也适用于所有三个 IDE,如果您使用的是 VS Code 或 Rider,请参阅上面的说明。

在 Visual Studio 中,打开函数项目,而不是测试项目。

在函数处理程序中放置一个断点。在 Web 用户界面中,添加您的函数输入,然后按执行。

如遇到断点,您可以像调试任何其他方法一样调试 Lambda 函数。

结论

在本模块中,您看到了通过命令行和 IDE 测试和调试 Lambda 函数的多种方法。

当您习惯编写 Lambda 函数时,您可能会在不同的函数测试方法之间切换,但强烈建议您尽快使用真正的 AWS Lambda 服务来测试您的代码。这是测试代码的最佳做法。

您还了解了如何在本地调试函数,从而可以逐步执行代码并查看结果。


知识测验

现在,您已经完成了模块 5 “单元测试和调试”。以下测试可让您检查到目前为止学到的内容。

1.哪些 IDE 允许您运行 Lambda 函数单元测试?(选择一个)

a.Visual Studio

b.VS Code

c.Rider

d.以上都是

2.AWS .NET Mock Lambda 测试工具可以让您做什么?(选择一个)

a.模拟测试的 .NET 依赖关系

b.模拟调用 Lambda 函数所需的 AWS 服务

c.对您的 Lambda 函数运行性能测试

d.在本地调用您的函数代码

3.Runtime Interface Emulator 适合哪种类型的 Lambda 函数?(选择一个)

a.托管运行时系统 Lambda 函数

b.基于容器的 Lambda 函数

c.自定义运行时系统 Lambda 函数

d.所有类型的 Lambda 函数

答案:1-d,2-d,3-b

结论

在本模块中,您看到了通过命令行和 IDE 测试和调试 Lambda 函数的多种方法。

当您习惯编写 Lambda 函数时,您可能会在不同的函数测试方法之间切换,但强烈建议您尽快使用真正的 AWS Lambda 服务来测试您的代码。这是测试代码的最佳做法。

您还了解了如何在本地调试函数,从而可以逐步执行代码并查看结果。

此页内容对您是否有帮助?

动手实验:创建并部署 Lambda 函数