Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Smart and efficient ways to test serverless architectures

Yan Cui
June 23, 2023

Smart and efficient ways to test serverless architectures

Serverless architectures allow developers to focus on their code, and not worry about infrastructure. But just because it's "serverless" doesn't mean it doesn't need testing! Whether you're working with API Gateway, AppSync, Step Functions or Event-Driven Architectures, I'll show you how to test it. Testing serverless doesn't have to be hard.

Yan Cui

June 23, 2023
Tweet

More Decks by Yan Cui

Other Decks in Technology

Transcript

  1. Hard Easy Lambdalith (e.g. express.js in Lambda) Step Functions with

    direct integrations Step Functions with timeouts or wait state(s) API Gateway with Lambda
  2. Hard Easy Lambdalith (e.g. express.js in Lambda) Step Functions with

    direct integrations Step Functions with timeouts or wait state(s) Event-Driven Architecture API Gateway with Lambda
  3. https://testserverlessapps.com Chapter 1: how to test serverless architectures Chapter 2:

    testing API Gateway APIs Chapter 3: testing AppSync APIs Chapter 4: testing Step Functions Chapter 5: testing Event-Driven Architectures Chapter 6: testing in production
  4. Test against mocks Test against real thing “does it work?”

    “does it do what I expect?” Expectations/Assumptions are sometimes wrong… Reality!
  5. Local testing Runs code locally Can use debugger Change code

    without deployment FAST FEEDBACK! Limited coverage Prone to false positives LOW CONFIDENCE
  6. HIGH CONFIDENCE! Local testing Remote testing Runs code locally Can

    use debugger Change code without deployment FAST FEEDBACK! Limited coverage Prone to false positives LOW CONFIDENCE Test in the cloud Realistic tests Better coverage
  7. HIGH CONFIDENCE! Local testing Remote testing Runs code locally Can

    use debugger Change code without deployment FAST FEEDBACK! Limited coverage Prone to false positives LOW CONFIDENCE Test in the cloud Realistic tests Better coverage Slow deployments Every change needs deploying… SLOW FEEDBACK…
  8. HIGH CONFIDENCE! Local testing Remote testing Runs code locally Can

    use debugger Change code without deployment FAST FEEDBACK! Limited coverage Prone to false positives LOW CONFIDENCE Test in the cloud Realistic tests Better coverage Slow deployments Every change needs deploying… SLOW FEEDBACK…
  9. REMOCAL testing Runs code locally, talk to real AWS services

    Can use debugger Change code without deployment Realistic tests
  10. Cognito API Gateway AppSync EventBridge IAM, event pattern, etc. IAM,

    URL path, method, etc. IAM, resolver con fi g, resolver template, etc.
  11. Auth Cognito AWS_IAM API Key Lambda authorizer Request validation Request

    transform Integration Lambda Direct service integration Domain logic Integrations Response transform IAM
  12. Auth Cognito AWS_IAM API Key Lambda authorizer Request validation Request

    transform Integration Lambda Direct service integration Domain logic Integrations Response transform IAM Unit Test Remocal Test E2E Test
  13. Auth Cognito AWS_IAM API Key Lambda authorizer Request validation Request

    transform Integration Lambda Direct service integration Domain logic Integrations Response transform IAM Unit Test Remocal Test E2E Test E2E Test E2E Test E2E Test E2E Test
  14. Auth Cognito AWS_IAM API Key Lambda authorizer Request validation Request

    transform Integration Lambda Direct service integration Domain logic Integrations Response transform IAM Unit Test Remocal Test E2E Test E2E Test E2E Test E2E Test E2E Test E2E Test E2E Test E2E Test E2E Test
  15. Auth Cognito AWS_IAM API Key Lambda authorizer Request validation Request

    transform Integration Lambda Direct service integration Domain logic Integrations Response transform IAM Unit Test Remocal Test E2E Test E2E Test E2E Test E2E Test E2E Test E2E Test E2E Test E2E Test E2E Test Unit Test Remocal Test
  16. REMOCAL testing Runs code locally, talk to real AWS services

    Can use debugger Change code without deployment Realistic tests AWS resources need to be provisioned
  17. npx sls deploy -s dev-my-feature Step 1: (creates a new

    “dev-my-feature” environment) Step 2: Make code changes, iterate, run remocal tests against the “dev-my-feature” environment
  18. npx sls deploy -s dev-my-feature Step 1: (creates a new

    “dev-my-feature” environment) Step 2: Make code changes, iterate, run remocal tests against the “dev-my-feature” environment Step 3: Commit code and send PR (CI pipeline runs all tests, etc.)
  19. npx sls deploy -s dev-my-feature Step 1: (creates a new

    “dev-my-feature” environment) Step 2: Make code changes, iterate, run remocal tests against the “dev-my-feature” environment Step 3: Commit code and send PR Step 4: npx sls remove -s dev-my-feature (destroys the ephemeral environment) (CI pipeline runs all tests, etc.)
  20. npx sls deploy -s dev-my-feature Step 1: (creates a new

    “dev-my-feature” environment) Step 2: Make code changes, iterate, run remocal tests against the “dev-my-feature” environment Step 3: Commit code and send PR Step 4: npx sls remove -s dev-my-feature (destroys the ephemeral environment) (CI pipeline runs all tests, etc.)
  21. npx sls deploy -s dev-my-feature Step 1: (creates a new

    “dev-my-feature” environment) Step 2: Make code changes, iterate, run remocal tests against the “dev-my-feature” environment Step 3: Commit code and send PR Step 4: npx sls remove -s dev-my-feature (destroys the ephemeral environment) (CI pipeline runs all tests, etc.) npx sls deploy -s ci-<SHA> Step 1: Step 2: npm run tests:all Step 3: npx sls remove -s ci-<SHA>
  22. Accounts dev test staging prod test dev staging prod dev-yan

    feature-a feature-b different CDK apps
  23. Accounts dev test staging prod test dev staging prod dev-yan

    feature-a feature-b combination of something
  24. #1: Don’t explicit name resources (unless you have to) “How

    do I make sure resource names don’t clash?”
  25. #1: Don’t explicit name resources (unless you have to) “How

    do I make sure resource names don’t clash?” #2: Include environment name in resource names
  26. The further away a state is, the harder it is

    to test (di ff i cult to direct execution along the desired path)
  27. yeah, it’s awkward… but it works and the best we’ve

    got right now… But mocked responses doesn’t skip time, and can’t throw timeout errors
  28. Hard Easy Lambdalith (e.g. express.js in Lambda) Step Functions with

    direct integrations Step Functions with timeouts or wait state(s) Event-Driven Architecture API Gateway with Lambda
  29. Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ

    EventBridge Component tests Unit Test Remocal Test
  30. Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ

    EventBridge Component tests Mocks Unit Test
  31. Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ

    EventBridge Component tests Mocks Unit Test
  32. Test against mocks Test against real thing “does it work?”

    “does it do what I expect?” Expectations/Assumptions are sometimes wrong… Reality!
  33. Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ

    EventBridge Component tests How to capture what was sent? Remocal Test
  34. Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ

    EventBridge E2E tests How to capture what was sent? How to capture what was sent? How to capture what was sent?
  35. Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ

    EventBridge E2E tests SNS How to capture what was sent?
  36. Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ

    EventBridge Component tests AppSync (subscription) Remocal Test
  37. #4: Capture async events/messages #3: Step Functions Local #2: Ephemeral

    environments #1: “remocal” testing for Lambda functions