서버리스 함수 및 애플리케이션을 테스트하는 방법 - AWS Lambda

서버리스 함수 및 애플리케이션을 테스트하는 방법

서버리스 함수 테스트는 기존 테스트 유형과 기법을 사용하지만, 서버리스 애플리케이션을 전체적으로 테스트하는 것도 고려해야 합니다. 클라우드 기반 테스트는 함수와 서버리스 애플리케이션 모두의 품질을 가장 정확하게 측정합니다.

서버리스 애플리케이션 아키텍처에는 API 호출을 통해 중요한 애플리케이션 기능을 제공하는 관리형 서비스가 포함됩니다. 따라서 개발 주기에는 함수와 서비스가 상호 작용할 때 기능을 확인하는 자동화된 테스트가 포함되어야 합니다.

클라우드 기반 테스트를 생성하지 않으면 로컬 환경과 배포된 환경 간의 차이로 인해 문제가 발생할 수 있습니다. 지속적 통합 프로세스는 QA, 스테이징 또는 프로덕션과 같은 다음 배포 환경으로 코드를 승격하기 전에 클라우드에서 프로비저닝되는 리소스 제품군을 대상으로 테스트를 실행해야 합니다.

이 짧은 안내서를 계속 읽고 서버리스 애플리케이션의 테스트 전략에 대해 알아보거나 Serverless Test Samples 리포지토리를 방문하여 선택한 언어 및 런타임과 관련된 실제 예제를 자세히 살펴보세요.

illustration showing the relationship between types of tests

서버리스 테스트의 경우에도 단위통합 및 엔드 투 엔드 테스트를 작성합니다.

  • 단위 테스트 - 격리된 코드 블록에 대해 실행되는 테스트입니다. 예를 들어, 특정 항목과 대상에 대한 배송료를 계산하는 비즈니스 로직을 확인합니다.

  • 통합 테스트 - 일반적으로 클라우드 환경에서 상호 작용하는 둘 이상의 구성 요소 또는 서비스를 포함하는 테스트입니다. 예를 들어, 함수가 대기열에서 이벤트를 처리하는지 확인합니다.

  • 엔드 투 엔드 테스트 - 전체 애플리케이션의 동작을 확인하는 테스트입니다. 예를 들어, 인프라가 올바르게 설정되어 있고 고객의 주문 기록을 위해 예상대로 서비스 간에 이벤트가 흐르는지 확인합니다.

목표 비즈니스 성과

서버리스 솔루션을 테스트하려면 서비스 간의 이벤트 기반 상호 작용을 확인하는 테스트를 설정하는 데 약간 더 많은 시간이 필요할 수 있습니다. 이 안내서를 읽을 때 다음과 같은 실질적인 비즈니스 이유를 염두에 두세요.

  • 애플리케이션 품질 향상

  • 기능 빌드 및 버그 수정 시간 단축

애플리케이션 품질은 기능을 확인하기 위한 다양한 시나리오 테스트에 따라 달라집니다. 비즈니스 시나리오를 신중하게 고려하고 이러한 테스트를 자동화하여 클라우드 서비스에 대해 실행하면 애플리케이션의 품질이 향상됩니다.

소프트웨어 버그 및 구성 문제는 반복적인 개발 주기 중 발견될 때 비용 및 일정에 미치는 영향이 가장 적습니다. 개발 중 문제가 발견되지 않은 경우 프로덕션에서 발견하고 수정하려면 더 많은 사람이 더 많은 노력을 기울여야 합니다.

잘 계획된 서버리스 테스트 전략은 Lambda 함수와 애플리케이션이 클라우드 환경에서 예상대로 작동하는지 확인하여 소프트웨어 품질을 높이고 반복 시간을 개선합니다.

테스트 대상

관리형 서비스 동작, 클라우드 구성, 보안 정책 및 코드와의 통합을 테스트하여 소프트웨어 품질을 개선하는 테스트 전략을 채택하는 것이 좋습니다. 블랙 박스 테스팅이라고도 하는 동작 테스트는 모든 내부 요소를 파악하지 않고도 시스템이 예상대로 작동하는지 확인합니다.

  • 단위 테스트를 실행하여 Lambda 함수 내부의 비즈니스 로직을 확인합니다.

  • 통합 서비스가 실제로 호출되고 입력 파라미터가 올바른지 확인합니다.

  • 이벤트가 워크플로에서 엔드 투 엔드로 예상되는 모든 서비스를 통과하는지 확인합니다.

기존 서버 기반 아키텍처에서는 팀이 애플리케이션 서버에서 실행되는 코드만 포함하도록 테스트 범위를 정의하는 경우가 많습니다. 다른 구성 요소, 서비스 또는 종속 항목은 외부 요소이며 테스트 범위를 벗어나는 것으로 간주되는 경우가 많습니다.

서버리스 애플리케이션은 데이터베이스에서 제품을 검색하거나 대기열에서 항목을 처리하거나 스토리지에서 이미지 크기를 조정하는 Lambda 함수와 같은 작은 작업 단위로 구성되는 경우가 많습니다. 각 구성 요소는 자체 환경에서 실행됩니다. 팀은 단일 애플리케이션 내에서 이러한 작은 단위 중 상당수를 담당하게 될 것입니다.

일부 애플리케이션 기능은 Amazon S3와 같은 관리형 서비스에 전적으로 위임하거나 내부에서 개발한 코드를 사용하지 않고 생성할 수 있습니다. 이러한 관리형 서비스를 테스트할 필요는 없지만 이러한 서비스와의 통합은 테스트해야 합니다.

서버리스 테스트 방법

로컬에 배포된 애플리케이션을 테스트하는 방법은 익히 알고 있을 것입니다. 데스크톱 운영 체제나 컨테이너 내에서 완전히 실행되는 코드를 대상으로 테스트를 작성합니다. 예를 들어, 요청으로 로컬 웹 서비스 구성 요소를 호출한 다음 응답에 대한 어설션을 만들 수 있습니다.

서버리스 솔루션은 함수 코드와 대기열, 데이터베이스, 이벤트 버스, 메시징 시스템 등의 클라우드 기반 관리형 서비스에서 구축됩니다. 이러한 구성 요소는 모두 이벤트라는 메시지가 한 리소스에서 다른 리소스로 흐르는 이벤트 기반 아키텍처를 통해 연결됩니다. 이러한 상호 작용은 웹 서비스가 결과를 즉시 반환하는 경우와 같이 동기식이거나 항목을 대기열에 배치하거나 워크플로 단계를 시작하는 것과 같이 나중에 완료되는 비동기식 작업일 수도 있습니다. 테스트 전략은 두 시나리오를 모두 포함하고 서비스 간 상호 작용을 테스트해야 합니다. 비동기 상호 작용의 경우 다운스트림 구성 요소에서 즉시 관찰할 수 없는 부작용을 감지해야 할 수 있습니다.

대기열, 데이터베이스 테이블, 이벤트 버스, 보안 정책 등을 포함한 전체 클라우드 환경을 복제하는 것은 실용적이지 않습니다. 로컬 환경과 클라우드에 배포된 환경의 차이로 인해 필연적으로 문제가 발생합니다. 환경의 차이로 인해 버그를 재현하고 수정하는 데 걸리는 시간이 늘어납니다.

서버리스 애플리케이션에서 아키텍처 구성 요소는 일반적으로 완전히 클라우드에 존재하므로 기능을 개발하고 버그를 수정하려면 클라우드의 코드 및 서비스에 대한 테스트가 필요합니다.

테스트 기법

실제로 테스트 전략에는 솔루션의 품질을 높이기 위한 다양한 기법이 포함될 수 있습니다. 콘솔에서 함수를 디버깅하기 위한 빠른 대화형 테스트, 격리된 비즈니스 로직을 확인하기 위한 자동화된 단위 테스트, 모의 객체로 외부 서비스에 대한 호출 확인, 서비스를 모방하는 에뮬레이터에 대한 간헐적 테스트 등을 사용합니다.

  • 클라우드에서 테스트 - 실제 서비스, 보안 정책, 구성 및 인프라 관련 파라미터로 테스트할 인프라 및 코드를 배포합니다. 클라우드 기반 테스트는 코드의 품질을 가장 정확하게 측정합니다.

    콘솔에서 함수를 디버깅하면 클라우드에서 빠르게 테스트할 수 있습니다. 샘플 테스트 이벤트 라이브러리에서 선택하거나 함수를 격리하여 테스트하는 사용자 지정 이벤트를 생성할 수 있습니다. 콘솔을 통해 팀과 테스트 이벤트를 공유할 수도 있습니다.

    개발 및 빌드 수명 주기에서 테스트를 자동화하려면 콘솔 외부에서 테스트해야 합니다. 자동화 전략 및 리소스는 이 안내서의 언어별 테스트 섹션을 참조하세요.

  • 모의(가짜라고도 함) 객체로 테스트 - 모의 객체는 코드 내에서 외부 서비스를 시뮬레이션하고 대신하는 객체입니다. 모의 객체는 서비스 호출과 파라미터를 확인하기 위해 사전 정의된 동작을 제공합니다. 가짜는 성능을 단순화하거나 개선하기 위해 바로 가기를 사용하는 모의 구현입니다. 예를 들어, 가짜 데이터 액세스 객체는 메모리 내 데이터 스토어에서 데이터를 반환할 수 있습니다. 모의 객체는 복잡한 종속 항목을 모방하고 단순화할 수 있지만 중첩된 종속 항목을 대체하기 위한 더 많은 모의 객체로 이어질 수도 있습니다.

  • 에뮬레이터로 테스트 - 로컬 환경에서 클라우드 서비스를 모방하도록 애플리케이션(경우에 따라 타사)을 설정할 수 있습니다. 속도는 강점이지만 설치 및 프로덕션 서비스와의 패리티는 약점입니다. 에뮬레이터는 적게 사용하세요.

클라우드에서 테스트

클라우드에서 테스트는 단위 테스트, 통합 테스트, 엔드 투 엔드 테스트 등의 모든 테스트 단계에서 중요합니다. 클라우드 기반 서비스와도 상호 작용하는 클라우드 기반 코드에 대해 테스트를 실행하면 코드 품질을 가장 정확하게 측정할 수 있습니다.

클라우드에서 Lambda 함수를 실행하는 편리한 방법은 AWS Management Console에서 테스트 이벤트를 사용하는 것입니다. 테스트 이벤트는 함수에 대한 JSON 입력입니다. 함수에 입력이 필요하지 않은 경우 이벤트는 빈 JSON 문서(({}))가 될 수 있습니다. 콘솔은 다양한 서비스 통합을 위한 샘플 이벤트를 제공합니다. 콘솔에서 이벤트를 생성한 후 팀과 공유하여 테스트를 더 쉽고 일관성 있게 만들 수도 있습니다.

콘솔에서 샘플 함수를 디버깅하는 방법을 알아보세요.

참고

콘솔에서 함수 실행이 빠른 디버깅 방법이지만 애플리케이션 품질과 개발 속도를 높이는 데는 테스트 주기 자동화가 필수입니다.

테스트 자동화 샘플은 Serverless Test Samples 리포지토리에서 사용할 수 있습니다. 다음 명령줄은 자동화된 Python 통합 테스트 예제를 실행합니다.

python -m pytest -s tests/integration -v

테스트는 로컬에서 실행되지만 클라우드 기반 리소스와 상호 작용합니다. 이러한 리소스는 AWS Serverless Application Model 및 AWS SAM 명령줄 도구를 사용하여 배포되었습니다. 테스트 코드는 먼저 API 엔드포인트, 함수 ARN 및 보안 역할을 포함하는 배포된 스택 출력을 검색합니다. 다음으로 테스트에서 API 엔드포인트에 요청을 보내고, API 엔드포인트는 Amazon S3 버킷 목록으로 응답합니다. 이 테스트는 클라우드 기반 리소스에 대해 전적으로 실행되어 해당 리소스가 예상대로 배포, 보호 및 작동하는지 확인합니다.

========================= test session starts ========================= platform darwin -- Python 3.10.10, pytest-7.3.1, pluggy-1.0.0 -- /Users/t/code/aws/serverless-test-samples/python-test-samples/apigw-lambda/venv/bin/python cachedir: .pytest_cache rootdir: /Users/t/code/aws/serverless-test-samples/python-test-samples/apigw-lambda plugins: mock-3.10.0 collected 1 item tests/integration/test_api_gateway.py::TestApiGateway::test_api_gateway --> Stack outputs: HelloWorldApi = https://p7teqs3162.execute-api.us-west-2.amazonaws.com/Prod/hello/ > API Gateway endpoint URL for Prod stage for Hello World function PythonTestDemo = arn:aws:lambda:us-west-2:1234567890:function:testing-apigw-lambda-PythonTestDemo-iSij8evaTdxl > Hello World Lambda Function ARN PythonTestDemoIamRole = arn:aws:iam::1234567890:role/testing-apigw-lambda-PythonTestDemoRole-IZELQQ9MG4HQ > Implicit IAM Role created for Hello World function --> Found API endpoint for "testing-apigw-lambda" stack... --> https://p7teqs3162.execute-api.us-west-2.amazonaws.com/Prod/hello/ API Gateway response: amplify-dev-123456789-deployment|myapp-prod-p-loggingbucket-123456|s3-java-bucket-123456789 PASSED ========================= 1 passed in 1.53s =========================

클라우드 네이티브 애플리케이션 개발의 경우 클라우드에서 테스트하면 다음과 같은 이점이 있습니다.

  • 사용 가능한 모든 서비스를 테스트할 수 있습니다.

  • 항상 최신 서비스 API와 반환 값을 사용하고 있습니다.

  • 클라우드 테스트 환경은 프로덕션 환경과 매우 유사합니다.

  • 테스트에서 보안 정책, 서비스 할당량, 구성 및 인프라 관련 파라미터를 다룰 수 있습니다.

  • 모든 개발자는 클라우드에서 하나 이상의 테스트 환경을 빠르게 생성할 수 있습니다.

  • 클라우드 테스트는 프로덕션에서 코드가 올바르게 실행될 것이라는 확신을 높여줍니다.

클라우드에서 테스트에는 몇 가지 단점이 있습니다. 클라우드에서 테스트의 가장 명백한 단점은 일반적으로 클라우드 환경에 배포가 로컬 데스크톱 환경에 배포보다 더 오래 걸린다는 것입니다.

다행히 AWS Serverless Application Model(AWS SAM) AccelerateAWS Cloud Development Kit(AWS CDK) 감시 모드 및 SST(타사)와 같은 도구는 클라우드 배포 반복과 관련된 지연 시간을 줄입니다. 이러한 도구는 인프라와 코드를 모니터링하고 클라우드 환경에 자동으로 증분적 업데이트를 배포할 수 있습니다.

참고

AWS Serverless Application Model, AWS CloudFormation 및 AWS Cloud Development Kit (AWS CDK)에 대해 자세히 알아보려면 Serverless Developer Guide의 코드형 인프라 생성 방법을 참조하세요.

로컬 테스트와 달리 클라우드에서 테스트에는 서비스 비용이 발생할 수 있는 추가 리소스가 필요합니다. 격리된 테스트 환경을 생성하면 DevOps 팀의 부담이 가중될 수 있습니다. 특히 계정과 인프라에 대한 통제가 엄격한 조직에서는 더욱 그렇습니다. 그렇더라도 복잡한 인프라 시나리오 작업 시 복잡한 로컬 환경을 설정하고 유지 관리하는 데 드는 개발자 시간 비용은 코드형 인프라 자동화 도구로 생성한 일회용 테스트 환경을 사용하는 것과 비슷하거나 더 높을 수 있습니다.

이러한 고려 사항에도 불구하고 클라우드에서 테스트가 여전히 서버리스 솔루션의 품질을 보장하는 가장 좋은 방법입니다.

모의 객체로 테스트

모의 객체로 테스트는 코드에 대체 객체를 생성하여 클라우드 서비스의 동작을 시뮬레이션하는 기법입니다.

예를 들어, CreateObject 메서드가 호출될 때마다 특정 응답을 반환하는 Amazon S3 서비스의 모의 객체를 사용하는 테스트를 작성할 수 있습니다. 테스트가 실행되면 모의 객체는 Amazon S3나 다른 서비스 엔드포인트를 호출하지 않고 프로그래밍된 응답을 반환합니다.

모의 객체는 종종 개발 노력을 줄이기 위해 모의 프레임워크에 의해 생성됩니다. 일부 모의 프레임워크는 일반적이고 나머지는 AWS 서비스 및 리소스 모의를 위한 Python 라이브러리인 Moto와 같이 AWS SDK용으로 특별히 설계되었습니다.

모의 객체는 일반적으로 개발자가 테스트 코드의 일부로 생성하거나 구성한다는 점에서 에뮬레이터와 다른 반면 에뮬레이터는 에뮬레이션하는 시스템과 동일한 방식으로 기능을 노출하는 독립 실행형 애플리케이션입니다.

모의 객체를 사용하면 다음과 같은 이점이 있습니다.

  • 모의 객체는 해당 서비스에 직접 액세스할 필요 없이 API 및 서비스형 소프트웨어(SaaS 공급자와 같이 애플리케이션의 제어 범위를 벗어나는 타사 서비스를 시뮬레이션할 수 있습니다.

  • 모의 객체는 특히 서비스 중단과 같이 장애 조건을 시뮬레이트하기 어려운 경우 장애 조건을 테스트하는 데 유용합니다.

  • 모의 객체는 일단 구성되면 빠른 로컬 테스트를 제공할 수 있습니다.

  • 모의 객체는 거의 모든 종류의 객체에 대한 대체 동작을 제공할 수 있으므로 모의 전략은 에뮬레이터보다 더 다양한 서비스에 대한 적용 범위를 생성할 수 있습니다.

  • 새로운 기능이나 동작을 사용할 수 있게 되면 모의 테스트를 통해 보다 신속하게 대응할 수 있습니다. 일반 모의 프레임워크를 사용하면 업데이트된 AWS SDK를 사용할 수 있게 되는 즉시 새로운 기능을 시뮬레이션할 수 있습니다.

모의 테스트에는 다음과 같은 단점이 있습니다.

  • 모의 객체에는 일반적으로 상당한 양의 설정 및 구성 작업이 필요하며, 특히 응답을 제대로 모의하기 위해 다양한 서비스의 반환 값을 결정하려고 할 때 그렇습니다.

  • 모의 객체는 개발자가 작성 및 구성하고 유지 관리해야 하므로 개발자의 책임이 가중됩니다.

  • 서비스의 API 및 반환 값을 이해하려면 클라우드에 액세스해야 할 수 있습니다.

  • 모의 객체는 유지 관리하기 어려울 수 있습니다. 모의된 클라우드 API 서명이 변경되거나 반환 값 스키마가 진화하면 모의 객체를 업데이트해야 합니다. 새 API를 호출하기 위해 애플리케이션 로직을 확장하는 경우 모의 객체도 업데이트가 필요합니다.

  • 모의 객체를 사용하는 테스트는 데스크톱 환경에서는 통과하지만 클라우드에서는 실패할 수 있습니다. 결과가 현재 API와 일치하지 않을 수 있습니다. 서비스 구성과 할당량은 테스트할 수 없습니다.

  • 모의 프레임워크는 AWS Identity and Access Management(IAM) 정책 또는 할당량 제한을 테스트하거나 감지하는 데 제한이 있습니다. 승인이 실패하거나 할당량이 초과될 때 모의 객체가 시뮬레이션을 더 잘 수행하지만 테스트를 통해 실제 프로덕션 환경에서 어떤 결과가 발생할지 결정할 수는 없습니다.

에뮬레이션으로 테스트

에뮬레이터는 일반적으로 프로덕션 AWS 서비스를 모방하는 로컬에서 실행되는 애플리케이션입니다.

에뮬레이터에는 클라우드의 해당 API와 유사한 API가 있으며 유사한 반환 값을 제공합니다. 또한 API 호출로 시작되는 상태 변경을 시뮬레이션할 수 있습니다. 예를 들어 AWS SAM을 사용하여 함수를 빠르게 호출할 수 있도록 AWS SAM 로컬로 함수를 실행하여 Lambda 서비스를 에뮬레이션할 수 있습니다. 자세한 내용은 AWS Serverless Application Model 개발자 안내서의 AWS SAM local을 참조하세요.

에뮬레이터로 테스트의 이점은 다음과 같습니다.

  • 에뮬레이터는 빠른 로컬 개발 반복 및 테스트를 촉진할 수 있습니다.

  • 에뮬레이터는 로컬 환경에서 코드를 개발하는 데 익숙한 개발자에게 친숙한 환경을 제공합니다. 예를 들어 n 계층 애플리케이션 개발에 익숙한 경우 프로덕션 환경에서 실행되는 것과 유사한 데이터베이스 엔진과 웹 서버가 로컬 컴퓨터에서 실행되어 신속하고 격리된 로컬 테스트 기능을 제공할 수 있습니다.

  • 에뮬레이터는 개발자 클라우드 계정 등의 클라우드 인프라를 변경할 필요가 없으므로 기존 테스트 패턴으로 쉽게 구현할 수 있습니다.

에뮬레이터로 테스트에는 다음과 같은 단점이 있습니다.

  • 에뮬레이터는 특히 CI/CD 파이프라인에서 사용할 때 설정 및 복제하기 어려울 수 있습니다. 이로 인해 자체 소프트웨어를 관리하는 IT 직원이나 개발자의 워크로드가 증가할 수 있습니다.

  • 에뮬레이션된 기능과 API는 일반적으로 서비스 업데이트보다 지연됩니다. 이로 인해 테스트된 코드가 실제 API와 일치하지 않아 오류가 발생하고 새로운 기능의 채택에 방해가 될 수 있습니다.

  • 에뮬레이터에는 지원, 업데이트, 버그 수정, 기능 패리티 개선이 필요합니다. 이는 타사일 수 있는 에뮬레이터 작성자의 책임입니다.

  • 에뮬레이터에 의존하는 테스트는 로컬에서 성공적인 결과를 제공할 수 있지만 프로덕션 보안 정책, 서비스 간 구성 또는 Lambda 할당량 초과로 인해 클라우드에서는 실패합니다.

  • 사용 가능한 에뮬레이터가 없는 AWS 서비스가 많습니다. 에뮬레이션에 의존하는 경우 애플리케이션 일부에 대해 만족스러운 테스트 옵션이 없을 수 있습니다.

모범 사례

다음 섹션에서는 성공적인 서버리스 애플리케이션 테스트를 위한 권장 사항을 제공합니다.

Serverless Test Samples 리포지토리에서 테스트 및 테스트 자동화의 실제 예를 찾아볼 수 있습니다.

클라우드에서 테스트 우선 순위 지정

클라우드에서 테스트는 가장 안정적이고 정확하며 완전한 테스트 범위를 제공합니다. 클라우드 컨텍스트에서 테스트를 수행하면 비즈니스 로직뿐만 아니라 보안 정책, 서비스 구성, 할당량, 최신 API 서명 및 반환 값까지 종합적으로 테스트할 수 있습니다.

테스트 가능성을 위한 코드 구성

핵심 비즈니스 로직에서 Lambda 관련 코드를 분리하여 테스트와 Lambda 함수를 간소화할 수 있습니다.

Lambda 함수 핸들러는 이벤트 데이터를 받아 비즈니스 로직 메서드에 중요한 세부 사항만 전달하는 슬림 어댑터여야 합니다. 이 전략을 사용하면 Lambda 관련 세부 사항에 대해 걱정하지 않고 비즈니스 로직을 중심으로 포괄적인 테스트를 수행할 수 있습니다. AWS Lambda 함수는 테스트 중인 구성 요소를 생성하고 초기화하기 위해 복잡한 환경이나 많은 양의 종속 항목을 설정할 필요가 없습니다.

일반적으로 수신 이벤트 및 컨텍스트 객체에서 데이터를 추출하고 검증한 다음 비즈니스 로직을 수행하는 메서드로 입력을 전송하는 핸들러를 작성해야 합니다.

개발 피드백 루프 가속화

개발 피드백 루프를 가속화하기 위한 도구와 기법이 있습니다. 예를 들어, AWS SAM Accelerate와 AWS CDK 감시 모드 모두 클라우드 환경을 업데이트하는 데 필요한 시간을 줄입니다.

GitHub Serverless Test Samples 리포지토리의 샘플에서 이러한 기법 중 일부를 살펴봅니다.

또한 소스 컨트롤을 체크인한 후뿐만 아니라 개발 과정에서 가능한 한 빨리 클라우드 리소스를 생성하고 테스트하는 것이 좋습니다. 이를 통해 솔루션을 개발할 때 더 빠르게 탐색하고 실험할 수 있습니다. 또한 개발 시스템에서 배포를 자동화하면 클라우드 구성 문제를 더 빨리 발견하고 업데이트 및 코드 검토 프로세스에 낭비되는 노력을 줄일 수 있습니다.

통합 테스트에 집중

Lambda로 애플리케이션을 빌드할 때 구성 요소를 함께 테스트하는 것이 가장 좋습니다.

여러 아키텍처 구성 요소에 대해 실행되는 테스트를 통합 테스트라고 합니다. 통합 테스트의 목표는 구성 요소에서 코드가 실행되는 방식뿐만 아니라 코드를 호스팅하는 환경이 어떻게 작동하는지 이해하는 것입니다. 엔드 투 엔드 테스트는 전체 애플리케이션에서 동작을 확인하는 특수 유형의 통합 테스트입니다.

통합 테스트를 빌드하려면 클라우드 환경에 애플리케이션을 배포합니다. 로컬 환경에서 또는 CI/CD 파이프라인을 통해 이를 수행할 수 있습니다. 그런 다음 테스트 대상 시스템(SUT)을 실행하고 예상되는 동작을 검증하는 테스트를 작성합니다.

예를 들어, 테스트 대상 시스템은 API Gateway, Lambda 및 DynamoDB를 사용하는 애플리케이션일 수 있습니다. 테스트는 API Gateway 엔드포인트에 대한 합성 HTTP 호출을 수행하고 응답에 예상 페이로드가 포함되었는지 확인할 수 있습니다. 이 테스트는 AWS Lambda 코드가 올바른지, 그리고 각 서비스가 서비스 간 IAM 권한을 포함하여 요청을 처리하도록 올바르게 구성되었는지 검증합니다. 또한 DynamoDB의 최대 레코드 크기와 같은 서비스 할당량이 제대로 설정되었는지 확인하기 위해 다양한 크기의 레코드를 작성하도록 테스트를 설계할 수 있습니다.

세 가지 서비스로 구성된 테스트 대상 시스템을 보여주는 다이어그램.

격리된 테스트 환경 생성

클라우드에서 테스트에는 일반적으로 테스트, 데이터 및 이벤트가 중복되지 않도록 격리된 개발자 환경이 필요합니다.

한 가지 접근 방식은 각 개발자에게 전용 AWS 계정을 제공하는 것입니다. 이를 통해 공유 코드베이스에서 작업하는 여러 개발자가 리소스를 배포하거나 API를 호출하려고 할 때 발생할 수 있는 리소스 이름 지정과의 충돌을 피할 수 있습니다.

자동화된 테스트 프로세스에서 각 스택에 대해 고유한 이름의 리소스를 생성해야 합니다. 예를 들어 AWS SAM CLI sam deploy 또는 sam sync 명령이 고유한 접두사가 있는 스택을 자동으로 지정하도록 스크립트 또는 TOML 구성 파일을 설정할 수 있습니다.

개발자가 AWS 계정을 공유하는 경우도 있습니다. 이는 운영 또는 프로비저닝 및 구성에 많은 비용이 드는 리소스가 스택에 있기 때문일 수 있습니다. 예를 들어, 데이터를 올바르게 설정하고 시드하기 쉽도록 데이터베이스를 공유할 수 있습니다.

개발자가 계정을 공유하는 경우 소유권을 식별하고 중복을 제거하기 위해 경계를 설정해야 합니다. 이를 수행하는 한 가지 방법은 스택 이름 앞에 개발자 사용자 ID를 추가하는 것입니다. 널리 사용되는 또 다른 접근 방식은 코드 분기를 기반으로 스택을 설정하는 것입니다. 분기 경계를 사용하면 환경이 분리되지만 개발자는 관계형 데이터베이스와 같은 리소스를 계속 공유할 수 있습니다. 이 접근 방식은 개발자가 한 번에 둘 이상의 분기에서 작업할 때 가장 좋은 방법입니다.

클라우드에서 테스트는 단위 테스트, 통합 테스트, 엔드 투 엔드 테스트 등의 모든 테스트 단계에서 중요합니다. 적절한 격리를 유지하는 것은 필수이지만, 대개 프로덕션 환경과 최대한 유사한 QA 환경을 원합니다. 이러한 이유로 팀은 QA 환경을 위한 변경 제어 프로세스를 추가합니다.

사전 프로덕션 및 프로덕션 환경의 경우 일반적으로 계정 수준에서 경계가 설정되어 잡음이 많은 이웃 문제로부터 워크로드를 격리하고 최소 권한 보안 제어를 구현하여 중요한 데이터를 보호합니다. 워크로드에는 할당량이 있습니다. 테스트에서 프로덕션(잡음이 많은 이웃)에 할당된 할당량을 사용하거나 고객 데이터에 액세스하지 못하도록 할 수 있습니다. 로드 테스트는 프로덕션 스택에서 분리해야 하는 또 다른 활동입니다.

어떤 경우든 불필요한 지출 방지를 위해 경고 및 제어 기능을 갖춘 환경을 구성해야 합니다. 예를 들어, 생성할 수 있는 리소스의 유형, 계층 또는 크기를 제한하고 예상 비용이 지정된 임계값을 초과할 때 이메일 알림을 설정할 수 있습니다.

분리된 비즈니스 로직에 모의 객체 사용

모의 프레임워크는 빠른 단위 테스트를 작성하는 데 유용한 도구입니다. 이는 테스트에서 수학 또는 재무 계산이나 시뮬레이션과 같은 복잡한 내부 비즈니스 로직을 다룰 때 특히 유용합니다. 테스트 사례 또는 입력 변형이 많고 이러한 입력이 다른 클라우드 서비스에 대한 호출 패턴이나 내용을 변경하지 않는 단위 테스트를 찾아보세요.

모의 객체를 사용한 단위 테스트에서 다루는 코드는 클라우드에서의 테스트에서도 다루어야 합니다. 개발자 랩톱 또는 빌드 시스템 환경을 클라우드의 프로덕션 환경과 다르게 구성할 수 있으므로 이 방법이 권장됩니다. 예를 들어, Lambda 함수는 특정 입력 파라미터로 실행할 때 할당된 것보다 더 많은 메모리나 시간을 사용할 수 있습니다. 또는 코드에 동일한 방식으로 또는 전혀 구성되지 않은 환경 변수가 포함될 수 있으며, 이러한 차이로 인해 코드가 다르게 동작하거나 실패할 수 있습니다.

연결 지점 수에 따라 필요한 모의 객체를 구현하는 노력 정도가 높아지기 때문에 통합 테스트에서는 모의 객체의 이점이 적습니다. 엔드 투 엔드 테스트에서는 대개 모의 프레임워크로는 쉽게 시뮬레이션할 수 없는 상태와 복잡한 로직을 다루기 때문에 모의 객체를 사용하면 안 됩니다.

마지막으로 서비스 호출의 적절한 구현을 검증하기 위해 모의 클라우드 서비스를 사용하지 마세요. 대신 클라우드에서 클라우드 서비스를 호출하여 동작, 구성 및 기능적 구현을 검증하세요.

에뮬레이터는 적게 사용하세요.

에뮬레이터는 인터넷 액세스가 제한적이거나 신뢰할 수 없거나 느린 개발 팀과 같은 일부 사용 사례에서 편리할 수 있습니다. 그러나 대부분의 경우 에뮬레이터를 적게 사용하는 것이 좋습니다.

에뮬레이터를 피하여 최신 서비스 기능과 최신 API로 빌드하고 혁신할 수 있습니다. 기능 패리티를 달성하기 위해 공급업체 릴리스를 기다리지 않아도 됩니다. 여러 개발 시스템과 빌드 시스템을 구매하고 구성하는 데 드는 초기 비용과 지속적인 비용을 줄일 수 있습니다. 또한 사용 가능한 에뮬레이터가 없는 클라우드 서비스가 많다는 문제를 피할 수 있습니다. 에뮬레이션에 의존하는 테스트 전략은 이러한 서비스를 사용하는 것을 불가능하게 하거나(잠재적으로 비용이 더 많이 드는 해결 방법으로 이어짐) 제대로 테스트되지 않은 코드와 구성을 생성합니다.

테스트에 에뮬레이션을 사용하는 경우에도 클라우드에서 테스트하여 구성을 확인하고 에뮬레이션된 환경에서만 시뮬레이션하거나 모의할 수 있는 클라우드 서비스와의 상호 작용을 테스트해야 합니다.

로컬 테스트 문제

에뮬레이터와 모의 호출을 사용하여 로컬 데스크톱에서 테스트하면 CI/CD 파이프라인의 환경 간에 코드가 진행되면서 테스트 불일치가 발생할 수 있습니다. 데스크톱에서 애플리케이션의 비즈니스 로직을 검증하기 위한 단위 테스트는 클라우드 서비스의 중요한 측면을 정확하게 테스트하지 못할 수 있습니다.

다음 예제에서는 모의 객체와 에뮬레이터를 사용하여 로컬에서 테스트할 때 주의해야 할 사례를 제공합니다.

예제: Lambda 함수에서 S3 버킷 생성

Lambda 함수의 로직이 S3 버킷 생성에 의존하는 경우 전체 테스트를 통해 Amazon S3가 호출되고 버킷이 성공적으로 생성되었는지 확인해야 합니다.

  • 모의 테스트 설정에서는 성공 응답을 모의하고 잠재적으로 실패 응답을 처리하기 위한 테스트 사례를 추가할 수 있습니다.

  • 에뮬레이션 테스트 시나리오에서 CreateBucket API가 호출될 수 있지만 로컬 호출을 수행하는 ID가 Lambda 서비스에서 시작되지 않는다는 점을 알고 있어야 합니다. 호출 ID는 클라우드에서와 같이 보안 역할을 수임하지 않으므로 자리 표시자 인증이 대신 사용되며 클라우드에서 실행될 때 달라질 수 있는 보다 허용적인 역할 또는 사용자 ID가 있을 수 있습니다.

모의 및 에뮬레이션 설정에서는 Lambda 함수가 Amazon S3를 호출할 경우 Lambda 함수가 수행할 작업을 테스트하지만, 구성된 대로 Lambda 함수가 Amazon S3 버킷을 성공적으로 생성할 수 있는지는 확인되지 않습니다. 함수에 할당된 역할에 함수가 s3:CreateBucket 작업을 수행할 수 있도록 허용하는 연결된 보안 정책이 있는지 확인해야 합니다. 그렇지 않으면 클라우드 환경에 배포할 때 함수가 실패할 수 있습니다.

예제: Lambda 함수에서 Amazon SQS 대기열의 메시지 처리

Amazon SQS 대기열이 Lambda 함수의 소스인 경우 전체 테스트를 통해 메시지가 대기열에 추가될 때 Lambda 함수가 성공적으로 호출되었는지 확인해야 합니다.

에뮬레이션 테스트와 모의 테스트는 일반적으로 Lambda 함수 코드를 직접 실행하고 JSON 이벤트 페이로드 또는 역직렬화된 객체를 함수 핸들러의 입력으로 전달하여 Amazon SQS 통합을 시뮬레이션하도록 설정됩니다.

Amazon SQS 통합을 시뮬레이션하는 로컬 테스트에서는 Amazon SQS가 지정된 페이로드와 함께 호출 시 Lambda 함수가 어떤 작업을 수행하는지 테스트하지만, Lambda 함수가 클라우드 환경에 배포될 때 Amazon SQS가 해당 함수를 성공적으로 호출하는지는 확인되지 않습니다.

다음은 Amazon SQS 및 Lambda에서 발생할 수 있는 구성 문제의 몇 가지 예입니다.

  • Amazon SQS 가시성 제한 시간이 너무 짧아 한 번만 의도했는데 여러 번 호출됩니다.

  • Lambda 함수의 실행 역할은 대기열에서 메시지 읽기를 허용하지 않습니다(sqs:ReceiveMessage, sqs:DeleteMessage 또는 sqs:GetQueueAttributes를 통해).

  • Lambda 함수에 전달된 샘플 이벤트가 Amazon SQS 메시지 크기 할당량을 초과합니다. 따라서 Amazon SQS에서는 해당 크기의 메시지를 전송할 수 없으므로 테스트가 유효하지 않습니다.

이러한 예에서 볼 수 있듯이 비즈니스 로직은 다루지만 클라우드 서비스 간의 구성은 다루지 않는 테스트는 신뢰할 수 없는 결과를 제공할 수 있습니다.

FAQ

다른 서비스를 호출하지 않고 계산을 수행하고 결과를 반환하는 Lambda 함수가 있습니다. 정말 클라우드에서 테스트해야 하나요?

예. Lambda 함수에는 테스트 결과를 변경할 수 있는 구성 파라미터가 있습니다. 모든 Lambda 함수 코드는 타임아웃메모리 설정에 종속되므로 해당 설정이 제대로 설정되지 않으면 함수가 실패할 수 있습니다. 또한 Lambda 정책은 Amazon CloudWatch에 표준 출력 로깅을 가능하게 합니다. 코드가 CloudWatch를 직접 호출하지 않더라도 로깅을 활성화하려면 권한이 필요합니다. 이 필수 권한은 정확하게 모의하거나 에뮬레이션할 수 없습니다.

클라우드에서 테스트가 단위 테스트에 어떻게 도움이 될 수 있나요? 클라우드에 있고 다른 리소스에 연결되면 통합 테스트가 아닌가요?

단위 테스트는 아키텍처 구성 요소에서 격리되어 작동하는 테스트로 정의되지만, 그렇다고 해서 다른 서비스를 호출하거나 일부 네트워크 통신을 사용할 수 있는 구성 요소가 테스트에 포함되지 않는 것은 아닙니다.

많은 서버리스 애플리케이션에는 클라우드에서도 격리하여 테스트할 수 있는 아키텍처 구성 요소가 있습니다. 한 가지 예는 입력을 받아 데이터를 처리하고 Amazon SQS 대기열로 메시지를 보내는 Lambda 함수입니다. 이 함수의 단위 테스트는 입력 값이 대기열에 있는 메시지에 특정 값을 표시하는지 여부를 테스트할 수 있습니다.

Arrange, Act, Assert 패턴을 사용하여 작성된 테스트를 고려하세요.

  • Arrange: 리소스(메시지 수신을 위한 대기열 및 테스트 중인 함수)를 할당합니다.

  • Act: 테스트 중인 함수를 호출합니다.

  • Assert: 함수에서 보낸 메시지를 검색하고 출력을 검증합니다.

모의 테스트 접근 방식에는 처리 중인 모의 객체로 대기열을 모의하고 Lambda 함수 코드가 포함된 클래스 또는 모듈의 처리 중인 인스턴스를 생성하는 것이 포함됩니다. Assert 단계에서는 대기열에 있는 메시지가 모의 객체에서 검색됩니다.

클라우드 기반 접근 방식에서는 테스트를 위해 Amazon SQS 대기열을 생성하고 격리된 Amazon SQS 대기열을 출력 대상으로 사용하도록 구성된 환경 변수와 함께 Lambda 함수를 배포합니다. Lambda 함수를 실행한 후 테스트는 Amazon SQS 대기열에서 메시지를 검색합니다.

클라우드 기반 테스트는 동일한 코드를 실행하고, 동일한 동작을 어설션하고, 애플리케이션의 기능적 정확성을 검증합니다. 그러나 Lambda 함수의 설정, 즉 IAM 역할, IAM 정책, 함수의 제한 시간 및 메모리 설정을 검증할 수 있다는 추가적인 이점이 있습니다.

다음 단계 및 리소스

다음 리소스를 사용하여 자세히 알아보고 실제 테스트 예제를 살펴보세요.

샘플 구현

GitHub의 Serverless Test Samples 리포지토리에는 이 가이드에 설명된 패턴 및 모범 사례를 따르는 테스트의 구체적인 예제가 포함되어 있습니다. 리포지토리에는 이전 섹션에서 설명한 모의, 에뮬레이션 및 클라우드 테스트 프로세스의 샘플 코드와 안내된 설명이 포함되어 있습니다. 이 리포지토리를 사용하여 AWS의 최신 서버리스 테스트 지침을 빠르게 확인하세요.

참조 자료

Serverless Land를 방문하여 AWS 서버리스 기술에 대한 최신 블로그, 비디오 및 교육에 액세스하세요.

다음 AWS 블로그 게시물도 읽어 보는 것이 좋습니다.

도구