Slide 1

Slide 1 text

smart and e ffi cient way to test serverless architectures

Slide 2

Slide 2 text

Yan Cui http://theburningmonk.com @theburningmonk AWS user since 2010

Slide 3

Slide 3 text

http://bit.ly/yubl-serverless

Slide 4

Slide 4 text

Developer Advocate @ Yan Cui http://theburningmonk.com @theburningmonk

Slide 5

Slide 5 text

Independent Consultant advise training delivery Yan Cui http://theburningmonk.com @theburningmonk

Slide 6

Slide 6 text

“how do I test serverless?”

Slide 7

Slide 7 text

Serverless > Lambda

Slide 8

Slide 8 text

“Use Lambda to transform data, not transport data”

Slide 9

Slide 9 text

AppSync DynamoDB AppSync DynamoDB Lambda

Slide 10

Slide 10 text

Step Functions

Slide 11

Slide 11 text

Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ EventBridge SNS

Slide 12

Slide 12 text

Serverless > Lambda, Serverless > APIs

Slide 13

Slide 13 text

Di ff erent services present di ff erent challenges to testing

Slide 14

Slide 14 text

Hard Easy

Slide 15

Slide 15 text

Hard Easy Lambdalith (e.g. express.js in Lambda)

Slide 16

Slide 16 text

Hard Easy Lambdalith (e.g. express.js in Lambda) API Gateway with Lambda

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

https://testserverlessapps.com

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

the RECIPE to TESTING serverless architectures

Slide 22

Slide 22 text

#1: “remocal” testing for Lambda functions

Slide 23

Slide 23 text

Local testing Runs code locally Can use debugger Change code without deployment FAST FEEDBACK!

Slide 24

Slide 24 text

Test against mocks Test against real thing “does it work?” “does it do what I expect?”

Slide 25

Slide 25 text

Test against mocks Test against real thing “does it work?” “does it do what I expect?” Expectations/Assumptions are sometimes wrong… Reality!

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

Local testing Runs code locally Can use debugger Change code without deployment FAST FEEDBACK! Limited coverage Prone to false positives LOW CONFIDENCE

Slide 28

Slide 28 text

Your application consists of more than just your code

Slide 29

Slide 29 text

Your application consists of more than just your code Your job is to ensure all of it works

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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…

Slide 32

Slide 32 text

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…

Slide 33

Slide 33 text

Local testing Remote testing

Slide 34

Slide 34 text

REMOCAL testing Runs code locally, talk to real AWS services Can use debugger Change code without deployment Realistic tests

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Cognito API Gateway AppSync EventBridge

Slide 37

Slide 37 text

Cognito API Gateway AppSync EventBridge IAM, event pattern, etc. IAM, URL path, method, etc. IAM, resolver con fi g, resolver template, etc.

Slide 38

Slide 38 text

Your application consists of more than just your code Your job is to ensure all of it works

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

DEMO TIME

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

#2: Ephemeral environments

Slide 47

Slide 47 text

npx sls deploy -s dev-my-feature Step 1: (creates a new “dev-my-feature” environment)

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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.)

Slide 50

Slide 50 text

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.)

Slide 51

Slide 51 text

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.)

Slide 52

Slide 52 text

Insulated environment for development and testing

Slide 53

Slide 53 text

Insulated environment for development and testing (avoids polluting shared dev/test/staging environments with test data)

Slide 54

Slide 54 text

No cost overhead with usage-based pricing

Slide 55

Slide 55 text

https://theburningmonk.com/2023/02/how-to-handle-serverful-resources-when-using-ephemeral-environments

Slide 56

Slide 56 text

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- Step 1: Step 2: npm run tests:all Step 3: npx sls remove -s ci-

Slide 57

Slide 57 text

environment !== AWS account

Slide 58

Slide 58 text

Accounts dev test staging prod test dev staging prod

Slide 59

Slide 59 text

Accounts dev test staging prod test dev staging prod dev-yan feature-a feature-b

Slide 60

Slide 60 text

Accounts dev test staging prod test dev staging prod dev-yan feature-a feature-b different stacks

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

Accounts dev test staging prod test dev staging prod dev-yan feature-a feature-b combination of something

Slide 63

Slide 63 text

“How do I make sure resource names don’t clash?”

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

#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

Slide 66

Slide 66 text

remocal testing + ephemeral environments = test Lambda functions with ease BUT…

Slide 67

Slide 67 text

Serverless > Lambda

Slide 68

Slide 68 text

Step Functions

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

{ “provider”: “stripe” }

Slide 71

Slide 71 text

{ “provider”: “stripe” }

Slide 72

Slide 72 text

{ “provider”: “stripe” } Check for execution result Validate side-effects

Slide 73

Slide 73 text

{ “provider”: “stripe” }

Slide 74

Slide 74 text

{ “provider”: “stripe” } How to make this step fail/timeout?

Slide 75

Slide 75 text

{ “provider”: “stripe” }

Slide 76

Slide 76 text

{ “provider”: “stripe” } How to make Stripe return a failed response?

Slide 77

Slide 77 text

The further away a state is, the harder it is to test (di ff i cult to direct execution along the desired path)

Slide 78

Slide 78 text

What I want to test

Slide 79

Slide 79 text

Timeout and Wait states are hard to test

Slide 80

Slide 80 text

#3: Step Functions Local

Slide 81

Slide 81 text

No content

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

state machine name

Slide 85

Slide 85 text

state name

Slide 86

Slide 86 text

state name response name

Slide 87

Slide 87 text

state name

Slide 88

Slide 88 text

No content

Slide 89

Slide 89 text

yeah, it’s awkward… but it works and the best we’ve got right now…

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

What I want to test rewrite the Wait state in local state machine

Slide 92

Slide 92 text

DEMO TIME

Slide 93

Slide 93 text

No content

Slide 94

Slide 94 text

Event-Driven Architecture in a nutshell: Something happened Do something

Slide 95

Slide 95 text

Event publisher Event consumer EventBridge

Slide 96

Slide 96 text

Asynchrony means you don’t know when the event has been processed.

Slide 97

Slide 97 text

Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ EventBridge

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ EventBridge Component tests

Slide 100

Slide 100 text

Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ EventBridge Component tests

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

Test against mocks Test against real thing “does it work?” “does it do what I expect?” Expectations/Assumptions are sometimes wrong… Reality!

Slide 105

Slide 105 text

Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ EventBridge Component tests Remocal Test

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ EventBridge E2E tests

Slide 108

Slide 108 text

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?

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

#4: Capture async events/messages

Slide 111

Slide 111 text

Lambda EventBridge System under test

Slide 112

Slide 112 text

Lambda EventBridge System under test AppSync (subscription)

Slide 113

Slide 113 text

Lambda EventBridge Push System under test AppSync (subscription)

Slide 114

Slide 114 text

Lambda EventBridge Push Shared infra AppSync (subscription)

Slide 115

Slide 115 text

service service service

Slide 116

Slide 116 text

Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ EventBridge AppSync (subscription)

Slide 117

Slide 117 text

Lambda EventBridge Lambda SNS Lambda DynamoDB Lambda DynamoDB SQS DLQ EventBridge Component tests AppSync (subscription) Remocal Test

Slide 118

Slide 118 text

DEMO TIME

Slide 119

Slide 119 text

#4: Capture async events/messages #3: Step Functions Local #2: Ephemeral environments #1: “remocal” testing for Lambda functions

Slide 120

Slide 120 text

No content

Slide 121

Slide 121 text

No content

Slide 122

Slide 122 text

productionreadyserverless.com 20% OFF with promo code “serverlessldn”

Slide 123

Slide 123 text

Questions?