Slide 1

Slide 1 text

Justin Bachorik 11.2.2018 Testing microservices in node.js

Slide 2

Slide 2 text

justinbach A little bit about me @justinbach on GitHub and Twitter

Slide 3

Slide 3 text

justinbach A little bit about Capital One

Slide 4

Slide 4 text

justinbach What we’ll cover 1. Testing: why and how? 2. Overview of microservice architecture 3. Testing microservices in node.js

Slide 5

Slide 5 text

justinbach Testing

Slide 6

Slide 6 text

justinbach Thought experiment #1

Slide 7

Slide 7 text

justinbach

Slide 8

Slide 8 text

justinbach Reasons to test

Slide 9

Slide 9 text

justinbach It’s all about the users!

Slide 10

Slide 10 text

justinbach A “classical” testing taxonomy

Slide 11

Slide 11 text

justinbach Unit tests

Slide 12

Slide 12 text

justinbach Failing unit tests as bug reports 1. Which component is being tested? 2. What behavior is being tested? 3. What are the actual results? 4. What are the expected results? 5. How can the actual results be reproduced? https://medium.com/javascript-scene/what-every-unit-test-needs-f6cd34d9836d

Slide 13

Slide 13 text

justinbach Integration tests

Slide 14

Slide 14 text

justinbach Functional tests

Slide 15

Slide 15 text

justinbach Other ways of classifying tests

Slide 16

Slide 16 text

justinbach Google’s small, medium, and large tests https://testing.googleblog.com/2010/12/test-sizes.html

Slide 17

Slide 17 text

justinbach White-box and black-box tests

Slide 18

Slide 18 text

justinbach Microservices

Slide 19

Slide 19 text

justinbach Thought experiment #2

Slide 20

Slide 20 text

justinbach

Slide 21

Slide 21 text

justinbach

Slide 22

Slide 22 text

justinbach Backend duties • User management • Dog inventory • Walk scheduling • Business reporting • Notifications • Client app API • Business API

Slide 23

Slide 23 text

justinbach Congrats, you’ve built a monolith! Wikimedia Commons

Slide 24

Slide 24 text

justinbach Puppies Microservices to the rescue! kitty.green66 / Flickr

Slide 25

Slide 25 text

justinbach

Slide 26

Slide 26 text

justinbach User management Dog inventory Walk scheduling Reporting Notifications

Slide 27

Slide 27 text

justinbach Advantages of microservices • Separation of concerns • Smaller, faster deployments • Technological heterogeneity • Resilience See https://martinfowler.com/articles/microservice-trade-offs.html for more

Slide 28

Slide 28 text

justinbach Microservices: Infrastructural tooling

Slide 29

Slide 29 text

justinbach Microservices: CI/CD pipeline

Slide 30

Slide 30 text

justinbach Microservices: Backends for frontends iPhone API Dog inventory Scheduling Tablet API Partner API

Slide 31

Slide 31 text

Justin Bachorik 11.2.2018 Testing microservices in node.js

Slide 32

Slide 32 text

justinbach A sample route GET /dogs [{ name: “Biscuit”, id: “df724ea3-beb8-4c97-a6a5-32acaba7bbad”, photo: “https://cdn.dogpool.com/img/b87f8fcd.jpg” }, // … more dogs? ]

Slide 33

Slide 33 text

justinbach Route topology Public API Auth Dogs GET /dogs Dog data

Slide 34

Slide 34 text

justinbach Route sequence diagram

Slide 35

Slide 35 text

justinbach Unit tests Dogs

Slide 36

Slide 36 text

justinbach Unit tests dog.js findByUserId() SQL rows

Slide 37

Slide 37 text

justinbach Method under test const findByUserId = async (db, userId) => { if (!userId) { throw new Error('findByUserId: must specify userId'); } return db.query(Sql.FIND_BY_USER, userId); };

Slide 38

Slide 38 text

justinbach Example: unit test describe('findByUserId', () => { it('should return dogs belonging to the user', async () => { await insertTestData(db, expectedData); // arrange const actualData = await Dog.findByUserId(db, userId); // act expect(actualData).to.deep.equal(expectedData); // assert await reset(db); }); });

Slide 39

Slide 39 text

justinbach Unit tests... ● ...exhaustively test methods, one code-path at a time ● ...live alongside the code under test ● ...are run on every commit and PR ● ...tend to be more white-box than other tests

Slide 40

Slide 40 text

justinbach Unit tests: tools 1. Testing framework (Mocha, Jest, Jasmine, Ava, Tape) 2. Assertion library (Assert, Should, Expect, Chai) 3. Mocking plugin (Sinon) 4. Coverage reporter (Istanbul, NYC)

Slide 41

Slide 41 text

justinbach Service integration tests Dogs GET /dogs?userId=... Dog data

Slide 42

Slide 42 text

justinbach Service integration tests... ● ...exercise the full request cycle at the microservice level ● ...validate routing and middleware configuration ● ...are run on every commit and PR ● ...are gray-box (requests to upstream services are mocked)

Slide 43

Slide 43 text

justinbach Service integration tests: tools All of our unit testing tools, plus Supertest!

Slide 44

Slide 44 text

justinbach Example: service integration test describe('GET /dogs?userId={userId}', () => { it('should return 200 and the correct dogs', async () => { const actualResponse = await request(app) .get(`/dogs?userId=${userId}`) .expect(200); expect.actualResponse.to.deepEqual(expectedResponse); }); });

Slide 45

Slide 45 text

justinbach Platform integration tests Public API Auth Dogs GET /dogs Dog data

Slide 46

Slide 46 text

justinbach Platform integration tests... ● ...can reside in Public API or an external repository ● ...are run against a full staging environment ● ...are completely black-box (except external service mocks)

Slide 47

Slide 47 text

justinbach 1. Testing framework (Mocha, Jest, Jasmine, Ava, Tape) 2. Assertion library (Assert, Chai, Should, Expect) 3. Request library (request-promise, fetch) 4. Service-mocking tool (WireMock) Platform integration tests: tools

Slide 48

Slide 48 text

justinbach Example: platform integration test describe('GET /dogs', () => { it('should return the current user’s dogs', async () => { const options = { method: 'GET', url: `${host}/dogs`, headers: `Bearer ${token}` }; const actualResponse = await rp(options); expect.actualResponse.to.deepEqual(expectedResponse); }); });

Slide 49

Slide 49 text

justinbach Extra credit: E2E tests Public API Authz Dogs GET /dogs Dog data

Slide 50

Slide 50 text

justinbach So, to recap... Unit tests Service integration tests Platform integration tests E2E tests

Slide 51

Slide 51 text

justinbach Thank you! Questions? [email protected]