Vue.jsのテスト
使用するテストフレームワーク
vue-test-utilsと呼ばれるテストフレームワークを使用します。Vue.jsの公式サイトにて推奨されているものです。
vue-test-utilsはコンポーネントを個々に分離してにマウントして、必要な入力をモックしたり、や出力をアサートしたりすることでテストを行います。
テストコードの概略を解説
テストコードの主要なメソッド
先ほど紹介したgithubに置かれているコードを使いながらテストコードについて解説していきます。まず下のコードがテストをする対象のコンポーネントのコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
export default { template: ` <div> <span class="count">{{ count }}</span> <button @click="increment">Increment</button> </div> `, data () { return { count: 0 } }, methods: { increment () { this.count++ } } } |
このコンポーネントはボタンをクリックするとカウンターが1ずつ増えていくものです。次のコードがテストコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// Import the mount() method from the test utils // and the component you want to test import { mount } from '@vue/test-utils' import Counter from './counter' describe('Counter', () => { // Now mount the component and you have the wrapper const wrapper = mount(Counter) it('renders the correct markup', () => { expect(wrapper.html()).toContain('<span class="count">0</span>') }) // it's also easy to check for the existence of elements it('has a button', () => { expect(wrapper.contains('button')).toBe(true) }) it('button should increment the count', () => { expect(wrapper.vm.count).toBe(0) const button = wrapper.find('button') button.trigger('click') expect(wrapper.vm.count).toBe(1) }) }) |
まずmountメソッドによってマウントされたcomponentはWrapper内に返されます。このWrapperはVueインスタンスを操作(mainpluating)、トラバース(travers)、クエリ(querying)したりするためのメソッドを公開しています。今回使ったメソッドは以下の4つ
html |
string型のhtml要素を返す |
contains |
指定したhtml要素を返す |
find |
指定したDOM NodeまたはVueコンポーネントを返す |
vm |
Vueインスタンスを返す |
この指定した要素に対して、出力条件を定義し、テストをしていきます。
Vueのテストを実行してみる
itに該当するテストの名前をつけることができます。以下のコードは<span class=”count”>0</span>が正しくレンダリングされたかどうかを確かめるコードです。
1 2 3 4 5 6 7 8 9 10 |
import { mount } from '@vue/test-utils' import Counter from './counter' describe('Counter', () => { const wrapper = mount(Counter) it('renders the correct markup', () => { expect(wrapper.html()).toContain('<span class="count">0</span>') }) } |
ではnpm testを叩いて上手くいくかどうかをテストしてみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
❯ npm test > vue-test-utils-getting-started@1.0.0 test /Users/~/vue-test-utils-getting-started > jest PASS ./test.js Counter ✓ renders the correct markup (3ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 1.354s Ran all test suites. |
renders the correct markupの部分にチェックが通ってテストが無事成功していることがわかります。では最後にあえてテストが失敗するようにテストコードを変更してみましょう。
1 2 3 4 5 6 7 8 9 10 |
import { mount } from '@vue/test-utils' import Counter from './counter' describe('Counter', () => { const wrapper = mount(Counter) it('renders the correct markup', () => { expect(wrapper.html()).toContain('<span class="count">1</span>') // 0→1 に変更 }) } |
実際のコードの初期値は0ですが、1に変更してテストを実行してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
❯ npm test > vue-test-utils-getting-started@1.0.0 test /Users/~/vue-test-utils-getting-started > jest FAIL ./test.js Counter ✕ renders the correct markup (4ms) ● Counter › renders the correct markup expect(string).toContain(value) Expected string: "<div><span class=\"count\">0</span> <button>Increment</button></div>" To contain value: "<span class=\"count\">1</span>" at Object.<anonymous> (test.js:11:28) at new Promise (<anonymous>) at processTicksAndRejections (internal/process/task_queues.js:93:5) Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 0.694s, estimated 1s Ran all test suites. npm ERR! Test failed. See above for more details. |
renders the correct markupでテストがこけていることが確認できました。
Vue-test-unitsを導入する方法
では実際に自分のVueのプロジェクトで使っているテスト環境構築方法について紹介します。package.jsonに以下の記述を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
"scripts": { ~~略 "test": "vue-cli-service test:unit" }, "dependencies": { "@babel/preset-env": "^7.6.3", ~~略 }, "devDependencies": { ~~略 "@babel/core": "^7.1.5", "@vue/cli-plugin-unit-jest": "^4.0.5", "@vue/test-utils": "^1.0.0-beta.29", "babel-jest": "^24.9.0", "jest": "^24.9.0", "vue-jest": "^3.0.5", }, "jest": { "moduleNameMapper": { "^vue$": "vue/dist/vue.common.js" }, "moduleFileExtensions": [ "js", "vue" ], "transform": { "^.+\\.js$": "<rootDir>/node_modules/babel-jest", ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest" } }, |
次に.babelrcを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "env": { "test": { "presets": [ [ "@babel/preset-env", { "targets": { "node": "current" } } ] ] } } } |
この状態でパッケージをインストールした後、npm run test
を叩くとテストをすることができます。



Vue.jsの単体テストvue-test-utilsの概要解説は以上です。間違い等がございましたらご指摘していただければ幸いです。
参考サイト
エンジニアにおすすめのアイテム
記事の内容とは別に、僕自身が保有する業務効率アップ、スキルアップを後押しするお勧めアイテムを紹介します。割とガチでお勧めなのです。
目の保温マッサージ
エンジニアの1日の業務は大半がディスプレイと睨めっこ。帰宅すると目が疲労で非常に重くなります。ひどい時は軽い頭痛になったりと結構深刻。そこで僕自身が毎日使っているのが目元マッサージ機です。



アイマッサージャーを使ってから、翌日の疲労感がだいぶ軽減されました。またマッサージ自体とっても気持ち良くて、布団に入るのが毎日楽しみになりました。コスパまじで最強アイテムです。
座椅子をゲーミングチェア風に
ディスプレイの長時間利用と同時にエンジニアは座椅子の上に何時間も座る運命にあります。椅子が快適だと疲労度が大きく変わると思った私は以下の2点のアイテムを購入しました。
IKSTAR クッション 低反発 座布団 第五世代 オフィス気に入りすぎて、オフィス用だけではなく、自宅用も購入してしまいました。導入してから長時間座ることでのお尻の痛みや、腰の痛みが激減しました。なので体の健康を考えるなら、導入するべきアイテムですね。