The three layers of testing @bartwaardenburg

“We want to deliver high quality applications for our users while regularly releasing new features”

00 Static analysis

Static analysis

“Static analysis is the analysis of software that is performed without actually executing programs”

“Using Flow or TypeScript could have prevented 15% of the public bugs for public projects on GitHub” http:// ttendency.cs.ucl.ac.uk /projects/ type_study /documents/ type_study.pdf

type MyCustomButtonProps = { text : string }; const MyCustomButton = ({ text }: MyCustomButtonProps ) => ( <button> { text } </button> ); const ButtonContainer = () => ( < MyCustomButton text

{ [ 'I' , 'like' , 'turtles' ] } /> );

“ You can have every single variable and function completely typed and linted but still have none of your functions doing what they should be doing”

const a : number

1 ; const b : number

2 ; const multiply = ( a : number , b : number ): number => a + b ; multiply ( a , b );

01 00 Static analysis Unit testing

Unit testing

“A unit test is a way of testing a unit

the smallest piece of code that can be logically isolated in a system”

const multiply = ( a : number , b : number ): number => a + b ; test ( 'Multiply should return the arguments multiplied' , () => { expect ( multiply ( 4 , 3 )). toBe ( 12 ); )};

expect( received ). toBe ( expected ) Expected value to be (using ===): 12 Received: 7

“ A snapshot test verifies that a piece of functionality works the same as it did when the snapshot was created ”

const Button = ({ type }: ButtonProps ) => ( <button className

{ ` btn

${ type }` } /> ); test ( 'The Button component renders correctly' , () => { const component

renderer . create ( <Button type

”good" /> ). toJSON (); expect ( component ). toMatchSnapshot (); });

PASS src / unit

test.spec.js ✓ The Button component renders correctly (11ms)

FAIL src / unit

test.spec.js ✕ The Button component renders correctly (15ms) ● The Button component renders correctly expect( value ). toMatchSnapshot () Received value does not match stored snapshot 1 .

Snapshot

  • Received <button

className =" btn

good" + className =" btn

bad" />

“ You can have every single component and function unit test passing but still have none of your functions working together like they should”

const multiply = ( a : number , b : number ): number => a * b ; const alertNumber = ( value : number ): void => alert ( value ); const ButtonWhichShouldAlertOnClick = () => ( <button onClick

{ () => multiply ( 1 , 2 ) } onMouseEnter

{ () => alertNumber ( multiply ( 1 , 2 )) }

Multiply </button> );

01 02 00 Static analysis Unit testing Integration testing

Integration testing

“Integration testing is the phase in software testing in which individual software modules are combined and tested as a group”

import { mount } from 'enzyme' ; const ButtonWhichShouldAlertOnClick = () => ( < button onClick

{ () => multiply ( 1 , 2 ) } onMouseEnter

{ () => alertNumber ( multiply ( 1 , 2 )) }

Multiply </button> ); alertNumber

jest . fn (); test ( 'The Button component should run a function on click' , () => { const component

mount ( <Button type

"test" /> ); component . find ( 'button' ). simulate ( 'click' ); expect ( alertNumber ). toHaveBeenCalledTimes ( 1 ); });

FAIL src / integration

test.spec.js ✕ The Button component should run a function on click (22ms) ● The Button component should run a function on click expect( jest.fn () ). toHaveBeenCalledTimes ( 1 ) Expected mock function to have been called one time , but it was called zero times .

“ You can have everything working together completely as intended but still have an empty screen for an application”

const multiply = ( a : number , b : number ): number => a * b ; const alertNumber = ( value : number ): void => alert ( value ); const Button = () => ( <button onClick

{ () => alertNumber ( multiply ( 1 , 2 )) }

Multiply </button> ); document . querySelector (‘ body' ). style . cssText

'display: none' ;

01 02 03 00 Static analysis Unit testing Integration testing User interface testing

User interface testing

“User interface testing is the process of testing a product's graphical user interface to ensure it meets its specifications”

t ools • Protractor • Cypress • Puppeteer • Codecept • Navalia • Chromeless • Selenium • Nightmare • Nightwatch • Te s t C a f e • CasperJS • Te s t C a f e

import { Chrome } from ' navalia ' ; import { toMatchImageSnapshot } from 'jest

image

snapshot' ; expect . extend ({ toMatchImageSnapshot }); const chrome

new Chrome (); test ( 'The routing input component should display as expected' , async () => { await chrome . goto ( 'https:// www.anwb.nl / verkeer / routeplanner ' ); await chrome . wait ( '.ROVE

routing

input' ); const screenshot

await chrome . screenshot ( '.ROVE

routing

input' ); await chrome . done (); expect ( screenshot ). toMatchImageSnapshot (); });

PASS src /components/routing

input

address/tests/ RoutingInputAddress.ui

test.js ( 7.153s ) ✓ The routing input component should display as expected (3671ms)

FAIL src /components/routing

input/tests/ RoutingInput.ui

test.js ( 9.909s ) ✕ The routing input component should display as expected (9033ms) ● The routing input component should display as expected Expected image to match or be a close match to snapshot. See diff for details: /Users/p279825/Sites/ANWB/traffic/ src /components/routing

input/tests/__ image_snapshots / diff_output __/routing

input

ui

test

js

the

routing

input

component

should

display

as

expected

1

diff.png

import { Chromeless } from ' chromeless ' ; const chromeless

new Chromeless (); const screenshot

await chromeless . goto ( 'https://www

ontw.anwb.nl / verkeer / routeplanner ' ) . screenshot ( '#routing' , { base64 : true , }); const file

new Buffer ( screenshot , 'base64' ); expect ( file ). toMatchImageSnapshot (); await chromeless . end ();

const chromeless

new Chromeless ({ remote : { endpointUrl : 'https://XXXXXXXXXX.execute

api.eu

west

1.amazonaws.com/dev’, apiKey : 'your

api

key

here’, }, });

“With chromeless you can run hundreds of browsers in parallel”

“You can easily execute > 100.000 tests for free in the free tier ”

01 02 03 00 Static analysis Unit testing Integration testing User interface testing

t hanks & happy testing @bartwaardenburg