Slide 1

Slide 1 text

End-to-End Testing Vue Apps with Cypress @amirrustam Vue Conf Toronto 2019

Slide 2

Slide 2 text

Head of Developer Experience @amirrustam Amir Rustamzadeh [email protected]

Slide 3

Slide 3 text

@amirrustam + Let’s keep to the conversation going after the talk… See something, tweet something. I’ll follow up with all questions and points of interest after the talk.

Slide 4

Slide 4 text

Let’s talk about testing @amirrustam but I’m not here to tell you to eat your broccoli

Slide 5

Slide 5 text

We need to change our perspective on where testing fits within the development lifecycle. @amirrustam

Slide 6

Slide 6 text

Testing is often an afterthought @amirrustam especially E2E tests

Slide 7

Slide 7 text

E2E Integration Unit Visit The Testing Pyramid Easy, developers really like to write these. More Difficult, costly, slower… Often completely ignored @amirrustam

Slide 8

Slide 8 text

You might of heard of Shift-left @amirrustam

Slide 9

Slide 9 text

Shift-left is a great direction, but it still segregates testing from development. @amirrustam

Slide 10

Slide 10 text

Testing can accelerate iteration during the implementation stage. @amirrustam I don’t mean TDD

Slide 11

Slide 11 text

We need to be able experiment as we’re figuring out the implementation. @amirrustam We’re often faced with new and unfamiliar libraries, patterns, components, etc.

Slide 12

Slide 12 text

Let’s look at some real world engineering examples @amirrustam

Slide 13

Slide 13 text

@amirrustam SpaceX Falcon Rocket Engine Controller Vibration Mitigation System

Slide 14

Slide 14 text

@amirrustam Mechanical Vibration Test System

Slide 15

Slide 15 text

@amirrustam Test Apparatus Mechanical Vibration Test System Engine Controller Instrumentation Simulate vibration scenarios Attached accelerometers tracked response/performance of implementation

Slide 16

Slide 16 text

@amirrustam Curiosity Mars Rover Actuator Electronic Ground Support Equipment (AEGSE)

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

@amirrustam Electronic Ground Support Equipment

Slide 19

Slide 19 text

@amirrustam Electronic Ground Support Equipment Simulate conditions on Mars to help with design/implementation iterations

Slide 20

Slide 20 text

Being able to consistently and reliably simulate real scenarios is key to quickly developing a viable implementation. @amirrustam

Slide 21

Slide 21 text

I wanted this same test apparatus for the web…. @amirrustam

Slide 22

Slide 22 text

Enter A tool to quickly and reliably test anything that runs in a browser. @amirrustam Free & Open Source (MIT License)

Slide 23

Slide 23 text

Stateless Stateful @amirrustam

Slide 24

Slide 24 text

$ npm install -D cypress ☝ All-in-one tool You get everything you need ❤ Familiar tools underneath Mocha, Chia, Sinon

Slide 25

Slide 25 text

Easy w/ Vue CLI @amirrustam

Slide 26

Slide 26 text

@amirrustam

Slide 27

Slide 27 text

@amirrustam

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Cypress is built with the developer experience (DX) as the top priority. @amirrustam

Slide 30

Slide 30 text

@amirrustam Command Log Your App

Slide 31

Slide 31 text

Human readable error messages Error Reporting is Important

Slide 32

Slide 32 text

Debuggability is Important Debug your app and tests at the same time

Slide 33

Slide 33 text

Time-travel through your app’s state and tests

Slide 34

Slide 34 text

Let’s check out the Cypress API @amirrustam Intuitive & English-like

Slide 35

Slide 35 text

@amirrustam cy. Cypress API

Slide 36

Slide 36 text

Cypress API @amirrustam cy.get('button')

Slide 37

Slide 37 text

Cypress API @amirrustam cy.get('button') .click() .should('have.class', 'active')

Slide 38

Slide 38 text

Cypress API @amirrustam cy.request('/users/1') .its('body') .should('deep.eql',{ name:'Amir'})

Slide 39

Slide 39 text

Cypress API @amirrustam cy.get('button') .click() .should('have.class', 'active') Subject is passed through the chain 1

Slide 40

Slide 40 text

Deterministic Execution Order @amirrustam it('send email with contact form', () => { cy.get('#name-input').type('Amir') cy.get('#email-input').type('[email protected]') cy.get('form').submit() cy.get('#success-message').should('be.visible') }) 1 2 3 4 Necessary for flake-free test runs

Slide 41

Slide 41 text

Cypress Architecture @amirrustam Browser Provisioning & System-level tasks Your App Your Tests Backend Browser

Slide 42

Slide 42 text

Cypress Architecture @amirrustam #1 Perk: Faster Test Runs &

Slide 43

Slide 43 text

@amirrustam cy.get('button') .click() .should('have.class', 'active') Cypress will wait up to 4 seconds (default) for this assertion to pass. Automatic Waiting Cypress will wait for the button to be clickable. Takes the guess-work out of arbitrary timeouts & pauses.

Slide 44

Slide 44 text

How should you approach testing an app? @amirrustam

Slide 45

Slide 45 text

@amirrustam Layers to Test Network Logic & State Interface

Slide 46

Slide 46 text

#1 Tip: Always test from the user’s perspective. Don’t waste time testing specific implementation. @amirrustam

Slide 47

Slide 47 text

@amirrustam Layers to Test Network Logic & State Interface Interact with the UI Spy & Stub (or mock) network requests Provision internal state and utilize internal logic to in test code Check for Visual Regressions

Slide 48

Slide 48 text

Spy or Stub Network Requests @amirrustam it('starts with zero items', () => { // start Cypress network server // spy on route `GET /todos` // THEN visit the page cy.server() cy.route('GET', '/todos').as('todos') cy.visit('/') cy .wait('@todos') // wait for `GET /todos` response // inspect the server's response .its('response.body') .should('have.length', 0) // then check the DOM cy.get('li.todo').should('have.length', 0) })

Slide 49

Slide 49 text

Spy or Stub Network Requests @amirrustam it('starts with zero items (fixture)', () => { // start Cypress network server // stub route `GET /todos`, return data from fixture file // THEN visit the page cy.server() cy.route('GET', '/todos', ‘fixture:sample-todos').as('todos') cy.visit('/') cy .wait('@todos') // wait for `GET /todos` response // inspect the server's response .its('response.body') .should('have.length', 0) // then check the DOM cy.get('li.todo').should('have.length', 0) })

Slide 50

Slide 50 text

Spy or Stub Network Requests @amirrustam

Slide 51

Slide 51 text

Utilizing Internal Logic & State @amirrustam const app = new Vue({ ... }) if (window.Cypress) { window.__app__ = app }

Slide 52

Slide 52 text

Utilizing Internal Logic & State @amirrustam const app = new Vue({ ... }) if (window.Cypress) { window.__app__ = app }

Slide 53

Slide 53 text

Utilizing Internal Logic & State @amirrustam cy.window().then(win => { return win.app.$store.dispatch('login', { email: '[email protected]', password: '1234' }) }) Use your app code to help you write your test code. It can be more efficient, and can provide a higher level of confidence.

Slide 54

Slide 54 text

Utilizing Internal Logic & State @amirrustam cy.window().then(win => { return win.app.$store.commit(‘SET_TODOS’, {…}) }) Provision the state of your app for testing

Slide 55

Slide 55 text

Utilizing Internal Logic & State @amirrustam cy.window().then(win => { cy.wait('@todos') .its('response.body.todos') .should('have.length', win.app.$store.state.todos.length) })

Slide 56

Slide 56 text

Isolated Component Tests @amirrustam import mount from 'cypress-vue-unit-test' import MyComponent from './app/components/MyComponent.vue' describe('My Component', () => { beforeEach(mount(MyComponent)) it('loads', () => { cy.get('button').should('be.visible') }) }) Experimental

Slide 57

Slide 57 text

@amirrustam Visual Regression Testing OSS Options and Paid Services on.cypress.io/visual-testing https://applitools.com/tutorials/cypress.html https://docs.percy.io/docs/cypress

Slide 58

Slide 58 text

@amirrustam Visual Regression Testing https://www.youtube.com/watch?v=3EJaforaVkA

Slide 59

Slide 59 text

How do I know when I’m done testing my app? @amirrustam

Slide 60

Slide 60 text

@amirrustam Code Coverage Use it to help guide your tests, but it’s not a silver-bullet. Write the minimum set of E2E tests to maximize coverage. Consider unit-tests for unreachable part of your code. Or refactor.

Slide 61

Slide 61 text

@amirrustam Code Coverage Use it to help guide your tests, but it’s not a silver-bullet. on.cypress.io/code-coverage

Slide 62

Slide 62 text

* cypress open Great for everyday development workflow Cypress + Editor Side-by-Side TDD Nirvana cypress run Testing in CI/CD Pipeline Headless More efficient for running all your tests @amirrustam

Slide 63

Slide 63 text

Automatic Screenshots and Video Recording in Headless Mode

Slide 64

Slide 64 text

cypress run --record --parallel Parallelization via Cypress Dashboard @amirrustam cypress.io/dashboard

Slide 65

Slide 65 text

cypress run --parallel cypress run --parallel cypress run --parallel Your CI Machines 3x parallelism Ready for work signup.spec.js login.spec.js widget.spec.js @amirrustam

Slide 66

Slide 66 text

Previous Spec Test Runs Spec Test Duration History Test Duration (seconds) The Future Automatic Load Balancing of Test Specs Duration Forecast @amirrustam

Slide 67

Slide 67 text

Automatic Load Balancing of Test Specs login.spec.js signup.spec.js widget.spec.js @amirrustam

Slide 68

Slide 68 text

@amirrustam cypress-example-kitchensink

Slide 69

Slide 69 text

@amirrustam cypress-dashboard 83%

Slide 70

Slide 70 text

@amirrustam Upcoming features from the Roadmap Full Network Layer Stubbing: You’ll be the master of the network. Great for handling GraphQL and fetch requests. Improved Error Reporting: From error to the point of the problem in your cord. Better communication of context around errors. Test Retries: Identify flake and save broken CI builds due to false negatives.

Slide 71

Slide 71 text

@amirrustam One more thing… Cross Browser: You’ve been waiting. We’ve been working.

Slide 72

Slide 72 text

@amirrustam One more thing… Firefox support coming out any day now. Let me show you….

Slide 73

Slide 73 text

@amirrustam Check out the Docs No really, do it. They are some of the best you’ll ever read. docs.cypress.io

Slide 74

Slide 74 text

@amirrustam There is a plugin for that Plugins for accessibility testing, visual testing, helpful utilities, etc. docs.cypress.io

Slide 75

Slide 75 text

docs.cypress.io/examples/examples/tutorials.html Tutorial Videos

Slide 76

Slide 76 text

Testing Workshop docs.cypress.io/examples/examples/workshop.html

Slide 77

Slide 77 text

@amirrustam We’re trying to change the status quo of testing. We want to testing to be enjoyable and productive. We’re only getting started.

Slide 78

Slide 78 text

@amirrustam Happy Testing ❤