Slide 1

Slide 1 text

Story time

Slide 2

Slide 2 text

Release Time!

Slide 3

Slide 3 text

Disaster!

Slide 4

Slide 4 text

The business’ footprint

Slide 5

Slide 5 text

Gregor Woiwode @GregOnNet [email protected] Softwarearchitekt co-IT.eu GmbH

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

Test Internal External API API Platform False-Positives Requirements

Slide 8

Slide 8 text

Test Internal External API API Platform False-Positives Requirements

Slide 9

Slide 9 text

How can we make tests more resilient?

Slide 10

Slide 10 text

1. Resiliency Process 2. Unit-Test Level 3. UI-Test Level

Slide 11

Slide 11 text

1

Slide 12

Slide 12 text

Run test case Identify resilience problems Identify resilience parameters Apply resilience parameters © IBM 2014

Slide 13

Slide 13 text

2

Slide 14

Slide 14 text

Adapter

Slide 15

Slide 15 text

Application Library

Slide 16

Slide 16 text

Application Library with

Slide 17

Slide 17 text

ttttttttt Application Library with

Slide 18

Slide 18 text

ttttttttt Application Library with

Slide 19

Slide 19 text

Application Library with brand new Library Are the tests still working?

Slide 20

Slide 20 text

Application Library with … using Adapter abstract your library

Slide 21

Slide 21 text

Applicationwith Library … using Adapter

Slide 22

Slide 22 text

Applicationwith Library … using Adapter

Slide 23

Slide 23 text

Applicationwith Library … using Adapter

Slide 24

Slide 24 text

Example

Slide 25

Slide 25 text

date-fns const yesterday = subDays(new Date(), 1); const tomorrow = addDays(new Date(), 1); moment.js const yesterday = moment().subtract(1, 'days').toDate(); const tomorrow = moment().add(1, 'days').toDate();

Slide 26

Slide 26 text

date-fns const yesterday = subDays(new Date(), 1); const tomorrow = addDays(new Date(), 1); moment.js const yesterday = moment().subtract(1, 'days').toDate(); const tomorrow = moment().add(1, 'days').toDate(); Library brand new Library

Slide 27

Slide 27 text

export class TimeKeeper { get yesterday() { return moment().subtract(1, 'days').toDate(); } get tomorrow() { return moment().add(1, 'days').toDate(); } } moment.js

Slide 28

Slide 28 text

export class TimeKeeper { get yesterday() { return subDays(new Date(), 1); } get tomorrow() { return addDays(new Date(), 1); } } date-fns

Slide 29

Slide 29 text

Adapter Benefits Saves time - One place of maintenance Stabilises In-App-API Simplifies faking

Slide 30

Slide 30 text

3

Slide 31

Slide 31 text

Isolated UI Tests

Slide 32

Slide 32 text

Template Level "" Application Level

Slide 33

Slide 33 text

Save" cy.get(‘.btn’) .should('exist');

Slide 34

Slide 34 text

Save" Cancel" cy.get(‘.btn’) .first() .should('exist');

Slide 35

Slide 35 text

Cancel" Save" cy.get(‘.btn’) .first() .should('exist');

Slide 36

Slide 36 text

Save" cy.get(‘.btn’) .should('exist');

Slide 37

Slide 37 text

Save" cy .get(‘[data-testid=view"__btn—save]’ ) .should('exist');

Slide 38

Slide 38 text

Save" Cancel" cy .get(‘[data-testid=view"__btn—save]’ ) .should('exist');

Slide 39

Slide 39 text

Application Level

Slide 40

Slide 40 text

Application /overview Testing a feature rich component

Slide 41

Slide 41 text

Application /overview Interact with data grid

Slide 42

Slide 42 text

Application /overview New requirement overlay

Slide 43

Slide 43 text

Application /products/reports/overview Clickable area is not reachable /overview

Slide 44

Slide 44 text

Application /products/reports/overview Component is moved in the app.

Slide 45

Slide 45 text

UI is fluent Widgets block test targets Test targets move

Slide 46

Slide 46 text

Application /products/reports/overview /overview

Slide 47

Slide 47 text

Application /products/reports/overview /overview Sandbox

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

Write a story about your component

Slide 50

Slide 50 text

export const primary = () "=> ({ }); Configure a story

Slide 51

Slide 51 text

export const primary = () "=> ({ "/* ""... "*/ component: DataGridComponent, }); Specify you UI component

Slide 52

Slide 52 text

export const primary = () "=> ({ "/* ""... "*/ component: DataGridComponent, props: { displayedColumns: ['position', 'name', 'weight', 'symbol'], dataSource: new MatTableDataSource([ { position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' }, { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' }, { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' } ]), }, }); Provide some test data

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

describe('common-ui', () "=> { beforeEach(() "=> cy.visit('/iframe.html?id=datagridcomponent"--primary')); it('should sort by number', () "=> { cy.get('[data-testid=data-grid"__header"--number]').click(); cy.get('[data-testid=data-grid"__header"--number]').click(); cy.get('[data-testid=data-grid"__header"--number-value]') .first() .should('contain', 10); }); }); Write an UI test for your component

Slide 55

Slide 55 text

nx.dev configures & runs

Slide 56

Slide 56 text

Example

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

Isolated UI Benefits Lower complexity of UI tests Focus on specific UI parts Get rid of side effects that break tests

Slide 59

Slide 59 text

Summary Clarified the why of test stability Learned about test resiliency process Adapter pattern stabilises Unit Tests Isolated UI Tests stabilise e2e Tests

Slide 60

Slide 60 text

Gregor Woiwode @GregOnNet [email protected] Softwarearchitekt co-IT.eu GmbH Zeit für Ihre Fragen…

Slide 61

Slide 61 text

Photo by Alex Wigan on Unsplash Photo by Chris Montgomery on Unsplash Photo by Bruno Martins on Unsplash Photo by Luke Stackpoole on Unsplash Photo by Steve Johnson on Unsplash Photo by Sigmund on Unsplash Image sources Photo by David Boca on Unsplash

Slide 62

Slide 62 text

Content Sources https://usersnap.com/blog/resilience-testing/ https://www.ibm.com/developerworks/websphere/techjournal/1407_col_nasser/1407_col_nasser.html https://kentcdodds.com/blog/making-your-ui-tests-resilient-to-change https://cypress.ui https://storybook.js.org https://nx.dev