Slide 1

Slide 1 text

JEST JEST ASSERTS ASSERTS BEYOND BEYOND EQUALS EQUALS 1

Slide 2

Slide 2 text

ABOUT ME ABOUT ME Software craftsperson at Software craftsperson at Codurance Codurance Oriented to software testing ( Oriented to software testing ( ) ) Testable Testable @MatheusMarabesi 🐦 @MatheusMarabesi 🐦 marabesi.com 💻 marabesi.com 💻

Slide 3

Slide 3 text

2 . 1

Slide 4

Slide 4 text

AGENDA 📖 AGENDA 📖 1. Background 2. Assertion smells 3. Assertion API 4. Exploring assertions 5. Wrapping up 3

Slide 5

Slide 5 text

This talk is based on my own journey . . . 4 . 1

Slide 6

Slide 6 text

Testing (TDD) 4 . 2

Slide 7

Slide 7 text

Framework (Jest) 4 . 3

Slide 8

Slide 8 text

toEqual toEqual, usually is the first assertion used ❗ , usually is the first assertion used ❗ 5 . 1

Slide 9

Slide 9 text

And, it's something like . . . 🤔 5 . 2

Slide 10

Slide 10 text

test('assert some value', () => { const myVar = 'some val' expect(myVar).toEqual('some val') ✅ }) 5 . 3

Slide 11

Slide 11 text

test('light is on', () => { const off = false expect(off === false).toEqual(true) ✅ }) 5 . 4

Slide 12

Slide 12 text

test('it has two users', () => { const users = [ { name: 'jhon'}, { name: 'maria' } ] expect(users.length).toEqual(2) ✅ }) 5 . 5

Slide 13

Slide 13 text

ASSERTION SMELLS ASSERTION SMELLS 6 . 1

Slide 14

Slide 14 text

WHEN TEST DRIVEN DEVELOPMENT GOES WRONG WHEN TEST DRIVEN DEVELOPMENT GOES WRONG By Continuous Delivery By Continuous Delivery When Test Driven Development Goes Wrong When Test Driven Development Goes Wrong 6 . 2

Slide 15

Slide 15 text

expect(myVar).equals('some val') ✅ const myVar = 'some val' 1 2 3 4 5 const off = false 6 7 expect(off === false).equals(true) ✅ 8 9 10 const users = [ 11 { name: 'jhon'}, 12 { name: 'maria' } 13 ] 14 15 expect(users.length).equals(2) ✅ 16 expect(off === false).equals(true) ✅ const myVar = 'some val' 1 2 expect(myVar).equals('some val') ✅ 3 4 5 const off = false 6 7 8 9 10 const users = [ 11 { name: 'jhon'}, 12 { name: 'maria' } 13 ] 14 15 expect(users.length).equals(2) ✅ 16 expect(users.length).equals(2) ✅ const myVar = 'some val' 1 2 expect(myVar).equals('some val') ✅ 3 4 5 const off = false 6 7 expect(off === false).equals(true) ✅ 8 9 10 const users = [ 11 { name: 'jhon'}, 12 { name: 'maria' } 13 ] 14 15 16 6 . 3

Slide 16

Slide 16 text

IS THERE A MORE EXPRESSIVE IS THERE A MORE EXPRESSIVE WAY? 🤔 WAY? 🤔 7

Slide 17

Slide 17 text

MEETING THE ASSERTION API MEETING THE ASSERTION API 5️⃣ 5️⃣ 8 . 1

Slide 18

Slide 18 text

Primitive assertions 🧱 8 . 2

Slide 19

Slide 19 text

Modifiers 🪣 8 . 3

Slide 20

Slide 20 text

Callbacks 📱 8 . 4

Slide 21

Slide 21 text

Async 🏹 8 . 5

Slide 22

Slide 22 text

Timers ⏰ 8 . 6

Slide 23

Slide 23 text

Primitive assertions 🧱 Primitive assertions 🧱 Modifiers 🪣 Modifiers 🪣 Callbacks 📱 Callbacks 📱 Async 🏹 Async 🏹 Timers ⏰ Timers ⏰ 8 . 7

Slide 24

Slide 24 text

PRIMITIVE ASSERTIONS 🧱 PRIMITIVE ASSERTIONS 🧱 test('it returns a number', () => { const isNumber = number => number expect(typeof isNumber(2)).toEqual('number') }) test('it returns a number', () => { const isNumber = number => number expect(isNumber(2)).toEqual( expect.any(Number) ) }) 9 . 1

Slide 25

Slide 25 text

test('expected is greater than the desired', () => { const expected = 10 const actual = 3 expect(expected > actual).toEqual(true) }) test('expected is greater than the desired', () => { const expected = 10 const actual = 3 expect(actual).toBeGreaterThan(expected) }) 9 . 2

Slide 26

Slide 26 text

ARRAYS 🧱 ARRAYS 🧱 test('list three fruits', () => { const expectedFruits = ['banana', 'mango', 'watermelon'] expect(expectedFruits[0]).toEqual('banana') expect(expectedFruits[1]).toEqual('mango') expect(expectedFruits[2]).toEqual('watermalo') }) test('list three fruits', () => { const expectedFruits = ['banana', 'mango', 'watermelon'] const actualFruits = () => ['banana', 'mango', 'watermelon'] expect(expectedFruits).toEqual( expect.arrayContaining(actualFruits) ) }) 10 . 1

Slide 27

Slide 27 text

test('list with three numbers', () => { const myList = [1, 2, 3] expect(myList.length).toEqual(3) }) test('list with three numbers', () => { const myList = [1, 2, 3] expect(myList).toHaveLength(3) }) 10 . 2

Slide 28

Slide 28 text

MODIFIERS 🪣 MODIFIERS 🪣 11 . 1

Slide 29

Slide 29 text

test('light is on', () => { const isOff = false expect(!isOff).toBe(true) }) test('light is on', () => { const isOff = false expect(isOff).not.toBe(true) }) 11 . 2

Slide 30

Slide 30 text

CALLBACKS 📱 CALLBACKS 📱 12 . 1

Slide 31

Slide 31 text

test('callback has been invoked', done => { callAsyncFunc(() => { expect(true).toEqual(true) done() }) }) 12 . 2

Slide 32

Slide 32 text

12 . 3

Slide 33

Slide 33 text

test('callback has been invoked', () => { const result = jest.fn() callAsyncFunc(result) expect(result).toHaveBeenCalled() }) 12 . 4

Slide 34

Slide 34 text

ASYNC 🏹 ASYNC 🏹 13 . 1

Slide 35

Slide 35 text

test('my async test', done => { callAsyncFunc(). then((value) => { expect(value).toBe(true) done() }) }) test('my async test', async () => { await expect(callAsyncFunc()).resolves.toEqual(true) }) test('my async test', async () => { await expect(callAsyncFunc()).rejects.toEqual(false) }) 13 . 2

Slide 36

Slide 36 text

TIMERS ⏰ TIMERS ⏰ 14 . 1

Slide 37

Slide 37 text

Eradicating Non-Determinism in Tests - Asynchronous Behavior Eradicating Non-Determinism in Tests - Asynchronous Behavior Martin Fowler, 2011 14 . 2

Slide 38

Slide 38 text

function callAsyncFunction() { return setTimeout(() => { return Promise.resolve(true) }, 1000) } test('assert after some time', done => { callAsyncFunc(). then((value) => { expect(value).toBe(true) done() }) }) 14 . 3

Slide 39

Slide 39 text

describe('using fake timers', () => { beforeEach(() => { jest.useFakeTimers() }) afterEach(() => { jest.restoreAllMocks() }) }) 14 . 4

Slide 40

Slide 40 text

test('should handle next scene', () => { const value = callAsyncFunc() jest.advanceTimersByTime(2000); expect(value).toBe(true) }) function callAsyncFunction() { return setTimeout(() => { return Promise.resolve(true) }, 1000) } 14 . 5

Slide 41

Slide 41 text

Timer mocks Timer mocks 14 . 6

Slide 42

Slide 42 text

WRAPPING UP 📔 WRAPPING UP 📔 15 . 1

Slide 43

Slide 43 text

toEqual toEqual is usually used more than any assertion is usually used more than any assertion 15 . 2

Slide 44

Slide 44 text

Using different assertions can improve Using different assertions can improve understading understading 15 . 3

Slide 45

Slide 45 text

HAPPY TESTING 🤪 HAPPY TESTING 🤪 15 . 4

Slide 46

Slide 46 text

Talk inspired by: Talk inspired by: 1. 2. 3. 4. Martin Fowler, Eradicating Non-Determinism in Tests (2011) jest extended Jest asserts beyond equals (2021) Jest timers and reactjs (2021) 15 . 5

Slide 47

Slide 47 text

ABOUT ME ABOUT ME Software craftsperson at Software craftsperson at Oriented to software testing ( Oriented to software testing ( ) ) Codurance Codurance Testable Testable @MatheusMarabesi 🐦 @MatheusMarabesi 🐦 marabesi.com 💻 marabesi.com 💻

Slide 48

Slide 48 text

16 . 1