Making it hard to  Vue wrong with linting and tests

Please fill out this quick survey!

https://chrisfritz.typeform.com/to/nSjsL1

Our backgrounds

What's our experience?

Who are you?

What will we cover?

  • Enabling best practices: how to avoid arguments and increase productivity by making it easy to do the right thing
  • Testing: making tests as painless and useful as possible
    • End-to-end tests (with Cypress)
    • Unit tests (with Jest)

Format

  1. Learn
  2. Question
  3. Apply

explanations

examples

stories

clarifications

what-ifs

code

experiment

one-on-one help

Resources

Vue Enterprise Boilerplate

please clone it now

Your Projects!

Participation tips

Raise your hand for questions at any time!

All examples are public

(no need to copy down code examples)

Please no recording

(for the privacy of participants)

Questions

Making it easy to follow best practices

Why?

Faster development

great tooling can not only catch typos and potential errors, but also teach new features as developers need them

More useful code reviews

Faster reviews, more learning, more motivating 

Higher quality code

when developers feel cared for by their tooling, they take more pride in their work and write better code

Great recruiting tool!

people get excited when they see a great architecture laid out

Replace (some) training with doc PRs

when trainees review doc PRs, training is made reusable

module.exports = {
  '*.{js,jsx}': [
    'eslint --fix',
    'prettier --write',
    'git add',
    'jest --bail --findRelatedTests',
  ],
  '*.json': ['prettier --write', 'git add'],
  '*.vue': [
    'eslint --fix',
    'stylelint --fix',
    'prettier --write',
    'git add',
    'jest --no-cache --bail --findRelatedTests',
  ],
  '*.scss': ['stylelint --fix', 'prettier --write', 'git add'],
  '*.md': ['markdownlint', 'prettier --write', 'git add'],
  '*.{png,jpeg,jpg,gif,svg}': ['imagemin-lint-staged', 'git add'],
}

Reduce friction

speed up development and simplify refactors

Enforce best practices

e.g. automatically generate a unit test with each module

Custom snippets

with Vetur

Same advantages as generators

Or use Sarah Drasner's snippets!

 

"vetur.completion.useScaffoldSnippets": false

Can be combined with generators for automatic basic tests for components, views, utils, etc.

Meta validations

Warn other devs when they might be using a component wrong

 

(when a prop's validator isn't enough)

Can even validate $listeners or $attrs

Global validation mixin

(only in development)

if (process.env.NODE_ENV !== 'production') {
  Vue.mixin({
    // Use lifecycle hooks to scan components for 
    // patterns that should be avoided.
  })
}

Questions

Practice

In the boilerplate

  • Save a file with a syntax or linting error, then try to commit the file.
  • Add a new Hygen generator for creating doc pages.
  • Create a new Jest matcher to assert that a component is functional. Try it on the nav-bar-routes.vue component.

In your app

  • Add one linter to your app, run with a lint command in package.json.

  • Use lint-staged to either lint or run unit tests against staged files (or both).

  • Add a meta validation to a component that your team has previously misused.

Testing

Biggest problems

we stop writing and running tests when they're NOT

Visible

Everyone knows when

tests are failing

Reliable

Tests don't fail intermittently

Fast

Tests run quickly

Debuggable

When a test fails,

it's easy to learn why

End-to-end tests

with Cypress

Why Cypress?

Writing e2e tests

Best practices

Don't maintain state between tests

they should be able to run with it.only

Don't select elements with classes

think from the user's perspective, or select elements by intent

Integrating e2e tests

Integrate into your review process

with continuous integration

Write and run in development

yarn dev:e2e in the boilerplate

Questions

Practice

In the boilerplate

  • Develop a small new feature using test-driven development with yarn dev:e2e. That means:

    1. First write the test

    2. Then develop the feature

In your app

Unit tests

with Vue Test Utils

and Jest

Why Vue Test Utils?

(currently in beta)

Mocks/stubs Vue components and properties

to full test a component's interface

Works with any test framework

Versatile rendering

including shallow rendering, to avoid testing subcomponents

Why Jest?

Great output on failure

Why Jest?

Quite fast

Why not Jest?

Not a real browser

uses JSDOM to simulate the browser

Have to reinvent your Webpack config

aliases, dynamic imports, etc require additional config

Writing unit tests

Don't test that Vue works

e.g. asserting that a data, computed, etc property exists

Build unit tests into generators

it's easier to add a new test when the file already exists

Pull out (potentially) shared logic

big components often scare people, so they go untested

Usually use a shallow render

otherwise, a problem in a common component can breaks many tests

Integrating unit tests

Never commit failing tests

run unit tests against staged files on a pre-commit hook

Continuous integration

make sure you know when tests are failing

Solve hard problems in setup files

create helpers and custom matchers to simplify complex assertions

First-class unit tests

Put unit tests next to the tested file

(e.g. hello.vue and hello.unit.js)

 

  • never think about organization of unit tests
  • missing tests are very obvious
  • helps onboard new developers, since they can see exactly what the file is supposed to do

Questions

Practice

In the boilerplate

  • Make a breaking change to a component and try to commit.
  • Make a change to a file that causes its test to fail. Now fix the test.
  • Use test-driven development on an existing component, first writing a test for a new feature, then adding the feature.

In your app

  • Refactor an existing component test to use Vue Test Utils (try the shallow render).

  • Delete a test that confirms Vue works.

  • Refactor your unit tests to be side-by-side with your source files.

That's all I know

Open practice time!

Making it hard to Vue wrong with linting and tests

By Chris Fritz

Making it hard to Vue wrong with linting and tests

The MIT License (MIT) Copyright (c) 2018-present Chris Fritz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

  • 702

More from Chris Fritz