|
| 1 | +# Testing Single File Components with Karma |
| 2 | + |
| 3 | +> An example project for this setup is available on [GitHub](https://github.com/eddyerburgh/vue-test-utils-karma-example). |
| 4 | +
|
| 5 | +Karma is a test runner that launches browsers, runs tests, and reports them back to us. We're going to use the Mocha framework to write the tests. We'll use the chai library for test assertions. |
| 6 | + |
| 7 | +## Setting up Jest |
| 8 | + |
| 9 | +We will assume you are starting with a setup that already has webpack, vue-loader and Babel properly configured - e.g. the `webpack-simple` template scaffolded by `vue-cli`. |
| 10 | + |
| 11 | +The first thing to do is install the test dependencies: |
| 12 | + |
| 13 | +``` bash |
| 14 | +npm install --save-dev @vue/test-utils karma karma-chrome-launcher karma-mocha karma-sourcemap-loader karma-spec-reporter karma-webpack mocha |
| 15 | +``` |
| 16 | + |
| 17 | +Next we need to define a test script in our `package.json`. |
| 18 | + |
| 19 | +```json |
| 20 | +// package.json |
| 21 | +{ |
| 22 | + "scripts": { |
| 23 | + "test": "karma start --single-run" |
| 24 | + } |
| 25 | +} |
| 26 | +``` |
| 27 | + |
| 28 | +- The `--single-run` flag tells Karma to run the test suite once. |
| 29 | + |
| 30 | +### Karma Configuration |
| 31 | + |
| 32 | +Create a karma.conf.js file in the index of the project: |
| 33 | + |
| 34 | +```js |
| 35 | +// karma.conf.js |
| 36 | + |
| 37 | +var webpackConfig = require('./webpack.config.js') |
| 38 | + |
| 39 | +module.exports = function (config) { |
| 40 | + config.set({ |
| 41 | + frameworks: ['mocha'], |
| 42 | + |
| 43 | + files: [ |
| 44 | + 'test/**/*.spec.js' |
| 45 | + ], |
| 46 | + |
| 47 | + preprocessors: { |
| 48 | + '**/*.spec.js': ['webpack', 'sourcemap'] |
| 49 | + }, |
| 50 | + |
| 51 | + webpack: webpackConfig, |
| 52 | + |
| 53 | + reporters: ['spec'], |
| 54 | + |
| 55 | + browsers: ['Chrome'] |
| 56 | + }) |
| 57 | +} |
| 58 | +``` |
| 59 | + |
| 60 | +This file is used to configure Karma. |
| 61 | + |
| 62 | +We need to preprocess our files with webpack. to do that, we add webpack as a preprocessor, and include our webpack config. We can use the webpack config file in the base of the project without changing anything. |
| 63 | + |
| 64 | +In our configuration, we run the tests in Chrome. To add extra browsers, see [the Browsers section in the Karma docs](http://karma-runner.github.io/2.0/config/browsers.html). |
| 65 | + |
| 66 | +### Picking an Assertion Library |
| 67 | + |
| 68 | +[Chai](http://chaijs.com/) is a popular assertion library that is commonly used alongside Mocha. You may also want to check out [Sinon](http://sinonjs.org/) for creating spies and stubs. |
| 69 | + |
| 70 | +We can install the `karma-chai` plugin to use `chai` in our tests. |
| 71 | + |
| 72 | +``` bash |
| 73 | +npm install --save-dev karma-chai |
| 74 | +``` |
| 75 | + |
| 76 | +### Adding a test |
| 77 | + |
| 78 | +Create a file in `src` named `Counter.vue`: |
| 79 | + |
| 80 | +``` html |
| 81 | +<template> |
| 82 | + <div> |
| 83 | + {{ count }} |
| 84 | + <button @click="increment">Increment</button> |
| 85 | + </div> |
| 86 | +</template> |
| 87 | + |
| 88 | +<script> |
| 89 | +export default { |
| 90 | + data () { |
| 91 | + return { |
| 92 | + count: 0 |
| 93 | + } |
| 94 | + }, |
| 95 | +
|
| 96 | + methods: { |
| 97 | + increment () { |
| 98 | + this.count++ |
| 99 | + } |
| 100 | + } |
| 101 | +} |
| 102 | +</script> |
| 103 | +``` |
| 104 | + |
| 105 | +And create a test file named `test/Counter.spec.js` with the following code: |
| 106 | + |
| 107 | +```js |
| 108 | +import { expect } from 'chai' |
| 109 | +import { shallow } from '@vue/test-utils' |
| 110 | +import Counter from '../src/Counter.vue' |
| 111 | + |
| 112 | +describe('Counter.vue', () => { |
| 113 | + it('increments count when button is clicked', () => { |
| 114 | + const wrapper = shallow(Counter) |
| 115 | + wrapper.find('button').trigger('click') |
| 116 | + expect(wrapper.find('div').text()).contains('1') |
| 117 | + }) |
| 118 | +}) |
| 119 | +``` |
| 120 | + |
| 121 | +And now we can run the tests: |
| 122 | + |
| 123 | +``` |
| 124 | +npm run test |
| 125 | +``` |
| 126 | + |
| 127 | +Woohoo, we got our tests running! |
| 128 | + |
| 129 | +### Coverage |
| 130 | + |
| 131 | +To setup code coverage to Karma, we can use the `karma-coverage` plugin. |
| 132 | + |
| 133 | +By default, `karma-coverage` won't use source maps to map the coverage reports. So we need to use `babel-plugin-istanbul` to make sure the coverage is mapped correctly. |
| 134 | + |
| 135 | +Install `karma-coverage`, `babel-plugin-istanbul`, and `cross-env`: |
| 136 | + |
| 137 | +``` |
| 138 | +npm install --save-dev karma-coverage cross-env |
| 139 | +``` |
| 140 | + |
| 141 | +We're going to use `cross-env` to set a `BABEL_ENV` environment variable. This way we can use babel-plugin-istanbul when we're compiling for our tests—we don't want to include `babel-plugin-istnabul` when we compile our production code: |
| 142 | + |
| 143 | +``` |
| 144 | +npm install --save-dev babel-plugin-istanbul |
| 145 | +``` |
| 146 | + |
| 147 | +Update your `.babelrc` file to use `babel-plugin-istanbul` when `BABEL_ENV` is set to test: |
| 148 | + |
| 149 | +```json |
| 150 | +{ |
| 151 | + "presets": [ |
| 152 | + ["env", { "modules": false }], |
| 153 | + "stage-3" |
| 154 | + ], |
| 155 | + "env": { |
| 156 | + "test": { |
| 157 | + "plugins": ["istanbul"] |
| 158 | + } |
| 159 | + } |
| 160 | +} |
| 161 | +``` |
| 162 | + |
| 163 | +Now update the karma.conf.js file to use coverage. Add `coverage` to the reporters array, and add a coverageReporters field: |
| 164 | + |
| 165 | +```js |
| 166 | +// karma.conf.js |
| 167 | + |
| 168 | +module.exports = function (config) { |
| 169 | + config.set({ |
| 170 | + // ... |
| 171 | + |
| 172 | + reporters: ['spec', 'coverage'], |
| 173 | + |
| 174 | + coverageReporter: { |
| 175 | + dir: './coverage', |
| 176 | + reporters: [ |
| 177 | + { type: 'lcov', subdir: '.' }, |
| 178 | + { type: 'text-summary' } |
| 179 | + ] |
| 180 | + } |
| 181 | + }) |
| 182 | +} |
| 183 | +``` |
| 184 | + |
| 185 | +And update the `test` script to set the `BABEL_ENV`: |
| 186 | + |
| 187 | +```json |
| 188 | +// package.json |
| 189 | +{ |
| 190 | + "scripts": { |
| 191 | + "test": "cross-env BABEL_ENV=test karma start --single-run" |
| 192 | + } |
| 193 | +} |
| 194 | +``` |
| 195 | + |
| 196 | +### Resources |
| 197 | + |
| 198 | +- [Example project for this setup](https://github.com/eddyerburgh/vue-test-utils-karma-example) |
| 199 | +- [Karma](http://karma-runner.github.io/) |
| 200 | +- [Mocha](https://mochajs.org/) |
| 201 | +- [Chai](http://chaijs.com/) |
| 202 | +- [Sinon](http://sinonjs.org/) |
0 commit comments