Skip to content

Instantly share code, notes, and snippets.

@aelbore
Last active May 30, 2020 03:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aelbore/998dc78af9183e6f13b27da1ac3a99db to your computer and use it in GitHub Desktop.
Save aelbore/998dc78af9183e6f13b27da1ac3a99db to your computer and use it in GitHub Desktop.
Vue 3 + Vite headless unit testing

Testing in Vue

Write lots of tests so people will afraid to delete yout code

alt text

Why need test?

  • Get an error if we break code
  • Save time (don't need to test manually)
    • It speeds up development because you don’t have to test everything manually after every change.
  • Integrate into build workflow
  • Improve your code

Different kind of Test

  • Unit Test
    • Fully isolated testing one function
  • Integration Test
    • Test with dependencies

Getting Started

mkdir vue-app
cd vue-app

npm init -y
npm i --save-dev vue@3.0.0-beta.9 @vue/compiler-sfc@b3.0.0-beta.14 vite

Create Vue App

  • Create src folder
  • Create ./src/App.vue
    <template>
     <div>
       <h1>Hello Vite + Vue 3!</h1>
       <p>Edit ./App.vue to test hot module replacement (HMR).</p>
       <p>
         <span>Count is: <span data-testid="button-counter">{{ count }}</span></span>
         <button @click="count++">increment</button>
       </p>
     </div>
    </template>
    
    <script>
    export default {
     data: () => ({ count: 0 })
    }
    </script>
    
    <style scoped>
    h1 { 
     color: #4fc08d;
    }
    
    h1, p {
     font-family: Arial, Helvetica, sans-serif;
    }
    </style> 
    • Create ./src/HelloWorld.vue
     <template>
       <p>
         Hello world!
       </p>
     </template>
    
     <script>
     export default {
     }
     </script>
    
     <style scoped>
     h1, p {
       font-family: Arial, Helvetica, sans-serif;
     }
     </style>
  • Create entry file main.js
    import {createApp} from 'vue'
    import App from './src/App.vue'
    
    createApp(App).mount('#app')
  • Create html file index.html
     <!DOCTYPE html>
     <html lang="en">
     <head>
       <meta charset="UTF-8"/>
       <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
       <title>⚡️ Vite + TDD</title>
       <style>
         body, html {
           font-family: Arial, Helvetica, sans-serif;
         }
       </style>
     </head>
       <body>
         <h1>
           ⚡️ Vite Component Test Starter
         </h1>
         <div id="app"></div>
         <script type="module" src="./main.js"></script>
       </body>
     </html>
  • Add or Update scripts in package.json
    • serve run your vue app into dev mode
      "scripts": {
        "serve": "vite"
      },

Add unit test your app

  • Install dependencies
    npm i --save-dev @vue/test-utils@2.0.0-alpha.6 aria-vue aria-mocha puppeteer
    
  • Add test
    • create ./test/App.spec.js
      import {mount} from '@vue/test-utils'
      import App from '../src/App.vue'
      
      describe('App.spec.js', () => {
        it('test button counter increments', async () => {
          const wrapper = mount(App, { attachTo: '#root' })
          const buttonCounterEl = wrapper.findByTestId('button-counter')
          expect(buttonCounterEl.textContent).to.equal('0')
          await wrapper.find('button').trigger('click')
          expect(buttonCounterEl.textContent).to.equal('1')
        })
      })
    • create ./test/HelloWorld.spec.js
    import {mount} from '@vue/test-utils'
    import HelloWorld from '../src/HelloWorld.vue'
    
    describe('HelloWorld.spec.js', () => {
      it('renders', async () => {
        const wrapper = mount(HelloWorld, { attachTo: '#root' })
        expect(wrapper.html()).to.contain('Hello')
      })
    })
    • create ./test/plugins.js this will execute/run before test or spec files
    import { config } from '@vue/test-utils'
    
    const DataTestIdPlugin = (wrapper) => {
      function findByTestId(selector) {
        const dataSelector = `[data-testid='${selector}']`
        const element = wrapper.element.querySelector(dataSelector)
        if (element) {
          return element
        }
        return null
      }
      return {
        findByTestId
      }
    }
    
    config.plugins.VueWrapper.install(DataTestIdPlugin)
  • Add or Update scripts in package.json
  "scripts": {
    "serve": "vite",
    "test": "aria-vue -w -H --script ./test/plugins.js"
  },
  • Run the test (everytime source or test files change it will run the tests with -w option)
npm test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment