AWS Lambda에서의 .NET 워크로드

모듈 5

모듈 5: 유닛 테스트 및 디버깅

 학습 모듈

여기에 제시된 예시를 따라할 수도 있지만 반드시 그럴 필요는 없습니다.

Lambda 함수를 테스트하는 방법에는 여러 가지가 있습니다. 가장 간단한 방법은 AWS Lambda 프로젝트 템플릿에 제공된 유닛 테스트를 사용하고 이를 기반으로 구축하는 것입니다. IDE의 친숙한 테스트 러너 또는 간단한 dotnet 테스트만 있으면 테스트를 실행할 수 있습니다.

또 다른 옵션은 AWS .NET Mock Lambda 테스트 도구를 사용하는 것입니다. 현재 평가판 진행 중입니다. 이를 통해 Lambda 함수를 테스트하고 디버깅할 수 있습니다. 이 도구는 AWS Toolkit for Visual Studio의 일부로 포함되어 있습니다. 하지만 다운로드해서 명령줄, VS Code 및 Rider와 함께 사용할 수 있습니다.

컨테이너에 배포되는 Lambda 함수를 개발하는 경우 Runtime Interface Emulator를 사용하여 컨테이너 내에서 실행되는 함수를 테스트할 수 있습니다.

로컬에서 함수를 테스트하는 데 사용할 수 있는 localstack과 같은 타사 도구가 있지만, 기능 테스트를 수행하는 가장 좋은 방법은 Lambda 함수를 AWS에 배포하고 거기에서 테스트하는 것입니다. AWS는 모든 계정에 매월 백만 건의 무료 요청과 매월 최대 320만 초의 컴퓨팅 시간을 제공합니다. 따라서 AWS 클라우드에서 기능을 테스트하지 않을 이유가 거의 없습니다.

요금에 대한 자세한 내용은 다음의 두 페이지를 참조하세요. AWS 프리 티어, 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 함수를 로컬에서 간접적으로 호출하고 응답을 검사할 수 있습니다.

위에서 언급한 것처럼 AWS Toolkit for Visual Studio를 사용하는 경우 도구가 이미 포함되어 있습니다.

이 도구는 Visual Studio, VS Code, Rider 또는 명령줄에서 사용할 수 있습니다.

명령줄을 사용하면 다음 두 가지 모드로 실행할 수 있습니다.

1. 웹 브라우저 기반 UI 사용

2. UI 없음

다음 몇 단계는 명령줄에서 도구를 사용하는 방법을 보여주지만 원하는 경우 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 옵션을 지정하고 페이로드를 전달해야 합니다. 페이로드의 이스케이프 처리는 사용 중인 쉘에 따라 달라집니다. 아래는 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 함수의 출력이 표시됩니다.

웹 UI 테스트, 명령줄에서 시작

명령줄에서 도구를 사용하여 테스트용 웹 UI를 시작할 수도 있습니다.

UI에서 페이로드를 직접 입력할 수 있지만, 이 경우 이스케이프 처리에 대해 걱정할 필요가 없습니다. 또는 일련의 예제 요청 페이로드 중에서 선택할 수 있습니다. 이를 통해 S3, Kinesis, SQS 등과 같은 다른 AWS 서비스의 요청을 시뮬레이션할 수 있습니다.

하지만 지금은 페이로드로 ‘hello’(따옴표 포함)를 입력하고 함수 실행 버튼을 누릅니다.

응답 섹션에서 함수가 반환한 내용을 확인할 수 있습니다.

함수에 로그문을 추가한 경우 로그 출력 섹션에 해당 로그문이 표시됩니다.

Visual Studio

AWS Toolkit for Visual Studio가 설치되어 있다면 이미 AWS .NET Mock Lambda 테스트 도구가 있는 것입니다.

Visual Studio에서 FunctionWithTestProject/src/FunctionWithTestProject 프로젝트를 엽니다.

Visual Studio는 속성 디렉터리를 생성하고, 이 디렉터리 안에 AWS .NET Mock Lambda 테스트 도구를 코드에 연결하는 launchsettings.json 파일을 생성합니다.

파일은 다음과 같이 나타납니다.
{
  "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-test-tool-6.0으로 변경해야 합니다.

2. Linux/Mac을 사용하는 경우 dotnet-lambda-test-tool-6.0에는 .exe 확장자가 없습니다.

Rider

AWS .NET Mock Lambda Test Tool for Rider를 구성하려면 다음 지침을
따르세요.

컨테이너 및 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 Client 또는 Rider Http Client와 함께 사용하기 위한 요청이 나와 있습니다.
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 요청을 무료로 실행할 수 있습니다. 이 한도를 초과하면 다음 백만 건의 실행 비용은 0.20 USD, 즉 실행당 0.0000002 USD가 됩니다. 메모리 사용량 및 실행 시간과 관련된 요금에는 몇 가지 주의 사항이 있습니다. 자세한 내용은 AWS 프리 티어 시작하기AWS 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 테스트 도구 사용

이는 세 가지 IDES 모두에서도 작동합니다. VS Code 또는 Rider를 사용하는 경우 위의 지침을 참조하세요.

Visual Studio에서 테스트 프로젝트가 아닌 함수 프로젝트를 엽니다.

함수 핸들러에 중단점을 설정합니다. 웹 UI에서 함수 입력을 추가하고 실행을 누릅니다.

중단점에 도달하면 다른 메서드와 마찬가지로 Lambda 함수를 디버깅할 수 있습니다.

결론

이 모듈에서는 명령줄과 IDE 모두에서 Lambda 함수를 테스트하고 디버깅하는 다양한 방법을 살펴보았습니다.

Lambda 함수를 작성하는 데 익숙해지면 함수를 테스트하는 다양한 방법 사이를 오갈 수 있지만 가능한 한 빨리 실제 AWS Lambda 서비스를 사용하여 코드를 테스트하는 것이 좋습니다. 테스트를 하기에 AWS Lambda 서비스가 가장 좋습니다.

또한 함수를 로컬에서 디버깅하는 방법을 살펴보면서 단계별로 어떤 일이 발생하는지 코드를 확인했습니다.


지식 확인

이제 모듈 5, 유닛 테스트 및 디버깅을 완료했습니다. 다음 테스트를 통해 지금까지 배운 내용을 확인할 수 있습니다.

1. Lambda 함수 유닛 테스트를 실행할 수 있는 IDE는 무엇인가요? (하나 선택)

a. Visual Studio

b. VS Code

c. Rider

d. 위의 모든 항목

2. AWS .NET Mock Lambda 테스트 도구를 사용하여 수행할 수 있는 작업은 무엇인가요? (하나 선택)

a. 테스트를 위한 Mock .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 서비스를 사용하여 코드를 테스트하는 것이 좋습니다. 테스트를 하기에 AWS Lambda 서비스가 가장 좋습니다.

또한 함수를 로컬에서 디버깅하는 방법을 살펴보면서 단계별로 어떤 일이 발생하는지 코드를 확인했습니다.

이 페이지의 내용이 도움이 되었나요?

실습: Lambda 함수 생성 및 배포