The what, why, and how
@eddyerburgh
// sum.js
function sum (a, b) {
return a + b
}
export default sum
// sum.spec.js
import sum from './sum'
test('returns sum of input', () => {
expect(sum(1,3)).toBe(4)
})
<template>
<div></div>
</template>
<script>
export default {
props: ['visible']
}
</script>
module.exports = {
render: function () {
var _vm=this;
var _h=_vm.$createElement;
var _c=_vm._self._c||_h;
return _c('div')
}
staticRenderFns: [],
props: ['visible']
}
Modal.vue
Modal.spec.js
Compiler
Test runner
github.com/eddyerburgh/vue-unit-test-perf-comparison
Test runner | 1000 | 5000 |
---|---|---|
tape | 9.s | 38s |
jest | 22s | 91s |
mocha-webpack | 11s | 38s |
karma-mocha | 33s | 119s |
ava | 625s | 7161s |
vue-test-utils.vuejs.org/en/guides/testing-SFCs-with-jest.html
$ npm install --save-dev jest vue-jest babel-jest
// package.json
{
// ..
"jest": {
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.vue$": "vue-jest"
},
}
// ..
}
// package.json
{
// ..
"scripts": {
"unit": "jest"
}
// ..
}
$ npm run unit
module.exports = {
render: function () {
var _vm=this;
var _h=_vm.$createElement;
var _c=_vm._self._c||_h;
return _c('div')
}
staticRenderFns: [],
props: ['visible']
}
$ npm install --save-dev @vue/test-utils
import { mount } from '@vue/test-utils'
import Modal from '../Modal.vue'
import { mount } from '@vue/test-utils'
import Modal from '../Modal.vue'
const wrapper = mount(Modal)
wrapper.vm
wrapper.element
import { mount } from '@vue/test-utils'
import Modal from '../Modal.vue'
const wrapper = mount(Modal)
Component
<modal-component
:visible="displayModal"
:onClose="closeModal"
>
Some content
</modal-component>
test('does not render when not passed visible prop', () => {
})
test('does not render when not passed visible prop', () => {
const wrapper = mount(Modal)
})
test('does not render when not passed visible prop', () => {
const wrapper = mount(Modal)
expect(wrapper.isEmpty()).toBe(true)
})
test('renders when passed visible prop as true', () => {
})
test('renders when passed visible prop as true', () => {
const wrapper = mount(Modal, {
propsData: {
visible: true
}
})
})
test('renders when passed visible prop as true', () => {
const wrapper = mount(Modal, {
propsData: {
visible: true
}
})
expect(wrapper.isEmpty()).toBe(false)
})
test('calls onClose when button is clicked', () => {
const onClose = jest.fn()
const wrapper = mount(Modal, {
propsData: {
visible: true,
onClose
}
})
wrapper.find('button').trigger('click')
expect(onClose).toHaveBeenCalled()
})
test('calls onClose when button is clicked', () => {
const onClose = jest.fn()
})
test('calls onClose when button is clicked', () => {
const onClose = jest.fn()
const wrapper = mount(Modal, {
propsData: {
visible: true,
onClose
}
})
})
test('calls onClose when button is clicked', () => {
const onClose = jest.fn()
const wrapper = mount(Modal, {
propsData: {
visible: true,
onClose
}
})
wrapper.find('button').trigger('click')
})
test('calls onClose when button is clicked', () => {
})
test('renders slot content')
<template>
<div v-if="visible">
<button @click="onClose" />
</div>
</template>
<script>
export default {
props: ['visible', 'onClose']
}
</script>
<template>
<div v-if="visible" class="modal is-active">
<div class="modal-background"></div>
<div class="modal-content">
<div class="box">
<button
@click="onClose"
class="delete"
aria-label="close"></button>
<slot />
</div>
</div>
</div>
</div>
</template>
test('renders correctly', () => {
const wrapper = mount(Modal, {
propsData: {
visible: true
}
})
})
test('renders correctly', () => {
})
test('renders correctly', () => {
const wrapper = mount(Modal, {
propsData: {
visible: true
}
})
expect(wrapper.html()).toMatchSnapshot()
})
Does previous
snapshot exist?
create snapshot
compare to previous
snapshot
test passes
No
Yes
does output
match
snapshshot?
create snapshot file
test fails
test passes
Yes
No
// Modal.spec.js.snap
exports[`renders correctly 1`] = `"<div class=\\"modal is-active\\"><div class=\\"modal-background\\"></div> <div class=\\"modal-content\\"><div class=\\"box\\"><button aria-label=\\"close\\" class=\\"delete\\"></button> </div></div></div>"`;
// package.json
{
// ..
"jest": {
// ..
"snapshotSerializers": [
"jest-serializer-vue"
],
// ..
}
// ..
}
$ npm install --save-dev jest-serializer-vue
$ npm run unit -- -u
test('renders correctly', () => {
})
test('renders correctly', () => {
const wrapper = mount(Modal, {
slots: {
default: '<p>some content</p>'
}
})
})
test('renders correctly', () => {
const wrapper = mount(Modal, {
slots: {
default: '<p>some content</p>'
},
propsData: {
visible: true
}
})
})
test('renders correctly', () => {
const wrapper = mount(Modal, {
slots: {
default: '<p>some content</p>'
},
propsData: {
visible: true
}
})
expect(wrapper.html()).toMatchSnapshot()
})
vue-test-utils.vuejs.org/