Slide 1

Slide 1 text

simalexan Meet Slobodan

Slide 2

Slide 2 text


Slide 3

Slide 3 text


Slide 4

Slide 4 text

simalexan Build with serverless! Its me!

Slide 5

Slide 5 text

simalexan No server management / ops Scales per use Autofailover Don’t pay 
 for idle

Slide 6

Slide 6 text

simalexan Business is more profitable Faster delivery

Slide 7

Slide 7 text

simalexan Code needs to run on servers! Serverless? That’s not the point! You’re an idiot

Slide 8

Slide 8 text

simalexan It is serverless, 
 the same way WIFI is wireless. Gojko Adzic

Slide 9

Slide 9 text


Slide 10

Slide 10 text

simalexan Ok, lets try…

Slide 11

Slide 11 text

simalexan AWS Lambda DynamoDB API Gateway AWS S3 To learn…

Slide 12

Slide 12 text

simalexan …the way it has changed…

Slide 13

Slide 13 text

simalexan to build…

Slide 14

Slide 14 text

simalexan …a functioning product

Slide 15

Slide 15 text

simalexan Accidents do happen Something will break…

Slide 16

Slide 16 text


Slide 17

Slide 17 text

simalexan …the business suffers

Slide 18

Slide 18 text

simalexan How do I prevent 
 this? You test!

Slide 19

Slide 19 text

simalexan We don’t have time to test! The you will find 
 time to fix!

Slide 20

Slide 20 text

simalexan Ok, how do I test a serverless app?

Slide 21

Slide 21 text

simalexan Testing Serverless Applications

Slide 22

Slide 22 text

simalexan Aleksandar Simovic Senior Software Engineer @ ScienceExchange AWS Serverless Hero coauthor of “Serverless Applications with Node.js” book AWS SAM & Lambda Builders Contributor

Slide 23

Slide 23 text

simalexan Why do you test?

Slide 24

Slide 24 text

simalexan • “Industry standard”. • “90% test coverage is required.” • “Code compliance”. • “You need to ensure that the code works”. The Usual replies

Slide 25

Slide 25 text

simalexan • “I don’t know, my CTO told me” • “I read HackerNews, I want to look smart” • “Because DHH said that.” • “Ensure quality.” The “real” replies

Slide 26

Slide 26 text

simalexan All (somewhat) 
 valid responses

Slide 27

Slide 27 text

simalexan The purpose of Testing is to find and prevent 

Slide 28

Slide 28 text

simalexan • John Null • E Lee • But Testing only to find or prevent
 defects is not enough

Slide 29

Slide 29 text


Slide 30

Slide 30 text

simalexan One of the purposes of testing is to Reduce Risk

Slide 31

Slide 31 text

simalexan What are these risks 
 when building serverless applications?

Slide 32

Slide 32 text

simalexan First, the way we build 
 applications has changed with serverless

Slide 33

Slide 33 text


Slide 34

Slide 34 text

simalexan Its risks…

Slide 35

Slide 35 text

simalexan • configuration risks • technical workflow risks • business logic risks • integration risks

Slide 36

Slide 36 text

simalexan Configuration risks Receiving events from the correct API? Access rights? Saving to correct bucket?

Slide 37

Slide 37 text

simalexan Technical workflow risks Handling success / error workflow responses Are we using the incoming events
 correctly? Workflow risks

Slide 38

Slide 38 text

simalexan Business logic 
 risks What is the correct structure 
 of our data By which order do we process our data? Is the file conversion correct? Are we saving in a correct folder in the bucket?

Slide 39

Slide 39 text

simalexan Integration risks Are our AppSync GraphQL objects properly set in DynamoDB? Are we reading AND
 writing events from API Gateway to S3 correctly?

Slide 40

Slide 40 text

simalexan How do we address those risks

Slide 41

Slide 41 text

simalexan Good Architecture

Slide 42

Slide 42 text

simalexan What is a good architecture for serverless?

Slide 43

Slide 43 text


Slide 44

Slide 44 text

simalexan Hexagonal Architecture

Slide 45

Slide 45 text

simalexan Alistair Cockburn Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases.

Slide 46

Slide 46 text

simalexan Boooring! 
 Show me an example

Slide 47

Slide 47 text

simalexan const AWS = require('aws-sdk'), stripe = require('stripe'), qs = require('querystring'), processResponse = require('./process-response'), stripe = require('stripe')(process.env.STRIPE_SECRET_KEY); exports.handler = async (event) => { if (!event.body) { return processResponse('invalid', 400); } const newCharge = qs.parse(event.body); if (!newCharge.amount || !newCharge.currency) { return 'invalid arguments, please provide amount and currency fields as mentioned in the app README'; } return await stripe.charges.create({ source: newCharge.stripeToken, amount: newCharge.amount, currency: newCharge.currency, description: 'Charge Description' }) };

Slide 48

Slide 48 text


Slide 49

Slide 49 text


Slide 50

Slide 50 text


Slide 51

Slide 51 text


Slide 52

Slide 52 text


Slide 53

Slide 53 text

simalexan Separate interface risk from your Business logic risk

Slide 54

Slide 54 text

simalexan In code..

Slide 55

Slide 55 text

simalexan const pubsubRepository = require('./pubsub-repository'), paymentProcessorRepository = require('./payment-processor'), TOPIC_ARN = process.env.TOPIC_ARN; module.exports = async function chargeCustomer( secretKey, token, email, amount, currency, description = 'Charge Description', paymentProcessor = paymentProcessorRepository, pubsub = pubsubRepository, subject = TOPIC_ARN ){ const createdCharge = await paymentProcessor.createCharge(secretKey, token, amount, currency, description); = email; await pubsub.publish(createdCharge, subject); return createdCharge; }

Slide 56

Slide 56 text

simalexan const AWS = require('aws-sdk'), sns = new AWS.SNS(), NO_DATA_REPLY = 'You must provide data to the your PubSub'; module.exports = { publish: async function publish( data, topic, pubSub = sns ){ return await pubSub.publish({ Message: JSON.stringify(data), TopicArn: topic }).promise(); } };

Slide 57

Slide 57 text

simalexan What do I test in a serverless app?

Slide 58

Slide 58 text

simalexan What do you test in a traditional app?

Slide 59

Slide 59 text


Slide 60

Slide 60 text

simalexan What is different in a serverless app?

Slide 61

Slide 61 text

simalexan Managed (and cheaper) infrastructure,
 many smaller business logic pieces

Slide 62

Slide 62 text


Slide 63

Slide 63 text

simalexan Even though with serverless your infrastructure is managed

Slide 64

Slide 64 text

simalexan That doesn’t mean your code is managed as well!

Slide 65

Slide 65 text

simalexan Integration tests are cheaper, but also more important, because a common serverless app is split into many small pieces

Slide 66

Slide 66 text

simalexan Testing your code and your integrations is now more important than before!

Slide 67

Slide 67 text

simalexan I know the 
 “Why”, “risks”, “What”… But now I need the “How”?

Slide 68

Slide 68 text

simalexan How to test serverless 

Slide 69

Slide 69 text

simalexan Just show me how in practice. Wait! 
 Stop using long words…

Slide 70

Slide 70 text

simalexan First, the tools!

Slide 71

Slide 71 text

simalexan Tools

Slide 72

Slide 72 text

simalexan • Jest • Jasmine • Mocha • Cypress • any other popular tool For example, for Node.js you can use:

Slide 73

Slide 73 text

simalexan Testing is very important on all levels both unit, integrated and end-to-end-testing.

Slide 74

Slide 74 text

simalexan Unit and integration tests!

Slide 75

Slide 75 text


Slide 76

Slide 76 text

simalexan Sample unit test code

Slide 77

Slide 77 text

simalexan const convertFromSentry = require('../src/convert-from-sentry'), lambdaProxyEvent = require('./test-events/lambda-proxy-event'), wrapEvent = (event) => { const result = JSON.parse(JSON.stringify(lambdaProxyEvent)); result.body = JSON.stringify(event); return result; }; describe('Convert from Sentry', () => { describe('Error type', () => { test('should pickup the error type if defined', () => { const event = wrapEvent(require('./test-events/raven-exception')); expect(convertFromSentry(event).type).toBe('TypeError'); }); test('should use runtime error type if undefined', () => { const event = wrapEvent(require('./test-events/raven-manually-tracked')); expect(convertFromSentry(event).type).toBe('RuntimeError'); }); }); describe('Error message', () => { test('should pickup the message if exception value defined', () => { const event = wrapEvent(require('./test-events/raven-exception')); expect(convertFromSentry(event).message).toBe(`Cannot read property 'captureException' of undefined`); }); test('should use body message if exception value undefined', () => { const event = wrapEvent(require('./test-events/raven-manually-tracked')); expect(convertFromSentry(event).message).toBe('error'); }); }); });

Slide 78

Slide 78 text

simalexan • hexagonal architecture • be smart • test integrations that you own • or test your code with a different adapter

Slide 79

Slide 79 text

simalexan If you test and properly design using Hexagonal architecture you’re even out of “vendor lock-in”.

Slide 80

Slide 80 text

simalexan UI testing

Slide 81

Slide 81 text

simalexan Benefits of serverless are cheap infrastructure and easy fast parallelization.

Slide 82

Slide 82 text


Slide 83

Slide 83 text

simalexan What about CI/CD?

Slide 84

Slide 84 text

simalexan It works the same way as it did
 with any other app

Slide 85

Slide 85 text

simalexan Use your favorite deployment tool from CI to deploy your serverless app

Slide 86

Slide 86 text

simalexan • Jenkins • Travis CI • AWS CodePipeline • Semaphore CI • CircleCI • and many more

Slide 87

Slide 87 text

simalexan Testing environments? And what about…

Slide 88

Slide 88 text

simalexan Having test environments was never cheaper

Slide 89

Slide 89 text

simalexan Automate deployment from git branches to different stages (ie. production, dev, staging, qa)

Slide 90

Slide 90 text

simalexan Testing slows you down! You’re making it sound too easy…

Slide 91

Slide 91 text

simalexan Actually…

Slide 92

Slide 92 text

simalexan Testing your serverless apps quickens your software delivery even more.

Slide 93

Slide 93 text

simalexan Real life example @ ScienceExchange

Slide 94

Slide 94 text

simalexan Hexagonal Architecture 3 months > 2 weeks Unit / Integration testing + = Going serverless + $40,000 > $10

Slide 95

Slide 95 text


Slide 96

Slide 96 text


Slide 97

Slide 97 text

simalexan • Testing your serverless applications is 
 more important than ever • One of the goals of testing is to reduce risk • use Hexagonal Architecture to stay flexible • serverless helps testers to do their job faster and cheaper • Testing serverless applications speeds up delivery Key takeaways

Slide 98

Slide 98 text


Slide 99

Slide 99 text

simalexan “Serverless Applications with Node.js" @simalexan claudia40 40% off Thank you!