基本的に大きなVue.jsアプリケーションを開発するとVue-cliで新しいプロジェクトを作成して、Babel、Jest、Webpackなどを入れます。複雑ですね。でもツールは全部JavaScriptなので、ブラウザだけでも使えます。
この記事で、Node.js、Webpackなどの複雑なツールなしでvue-test-utils
を使ってTDDで簡単なアプリケーションを作ります。ブラウザとスクリプトタグだけで書きます。
何を作る?
これは、MUST-DOアプリケーションです。TODOのようなアプリケーションですが、TODOを入れられないし、削除できないのでMUST-DOです。
ソースコードはここ。index.html
だけです。
Vueとテストを書くには必要なものは:
- Vue
- Vue-test-utils
- テストランナー (Mocha.jsを使います)
始めます。
検証は?
簡単なアプリケーションなので複雑な検証ライブラリーを使わないです。その代わりに、この関数を使います。
function assert(actual, expected) {
if (actual != expected) {
throw Error("やばい")
}
}
assert(1, 2) // => false
assert("A", "A") // => true
このテンプレートで始めます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.rawgit.com/vuejs/vue/dev/dist/vue.min.js"></script>
<script src="https://cdn.rawgit.com/vuejs/vue/dev/packages/vue-template-compiler/browser.js"></script>
<script src="https://cdn.rawgit.com/vuejs/vue-test-utils/dev/packages/test-utils/dist/vue-test-utils.iife.js"></script>
<link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
<script>mocha.setup('bdd')</script>
</head>
<body>
<div id="mocha"></div>
<script>
mocha.run()
</script>
</body>
</html>
script
が5個くらいがあります。
- Vue
- Vue template compiler (
vue-test-utils
がこれを使う) - vue test utils (Vueコンポーネントを簡単にテスト)
- mocha.js (テストランナー)
- mocha.css (Mocha.jsの結果をいい感じにレンダー)
条件
2つのコンポーネントに分けます。
MustDoList
-
MustDoItem
をレンダーする -
mustdos
変数を管理する
MustDoItem
-
id
とtext
をレンダーする
MustDoItem
から!
MustDoItem
最初のテストを書きましょう。
<script>
function assert(actual, expected) {
if (actual != expected) {
throw Error("やばい")
}
}
const { shallowMount } = VueTestUtils
describe("MustDoItem", () => {
it("idとtextをレンダーする", () => {
const wrapper = shallowMount(MustDoItem)
assert(wrapper.find(".id").text(), "1")
assert(wrapper.find(".text").text(), "テストを書く")
})
})
mocha.run()
</script>
そしてページをリフレッシュして:
どうなりました?
ReferenceError: MustDoItem is not defined
じゃ、作りましょう。
<script>
function assert(actual, expected) {
if (actual != expected) {
throw Error("やばい")
}
}
const MustDoItem = Vue.component('must-do-item', {
template: "<div></div>"
})
const { shallowMount } = VueTestUtils
describe("TodoItem", () => {
it("idとtextをレンダーする", () => {
const wrapper = shallowMount(MustDoItem)
assert(wrapper.find(".id").text(), "1")
assert(wrapper.find(".text").text(), "テストを書く")
})
})
mocha.run()
</script>
Error: [vue-test-utils]: find did not return .id,
cannot call text() on empty Wrapper
class="id"
が必要そうです。
const MustDoItem = Vue.component('must-do-item', {
template: `
<div>
<div class="id"></div>
<div class="text"></div>
</div>`
})
やばいまで進みました。id
、text
をレンダーしましょう。MustDoList
からprops
として受け取ります。
const MustDoItem = Vue.component('must-do-item', {
props: {
id: {
type: Number,
required: true
},
text: {
type: String,
required: true
}
},
template: `
<div>
<div class="id">{{ id }}</div>
<div class="text">{{ text }}</div>
</div>`
})
まだやばいです。テストも更新しないといけません:
describe("TodoItem", () => {
it("idとtextをレンダーする", () => {
const wrapper = shallowMount(MustDoItem, {
propsData: {
id: 1,
text: "テストを書く"
}
})
assert(wrapper.find(".id").text(), "1")
assert(wrapper.find(".text").text(), "テストを書く")
})
})
NOTやばい!!
MustDoList
MustDoList
は:
-
mustdos
配列をループして、 -
MustDoItem
をレンダーする
テストと簡単なコンポーネントを書きましょう。
const MustDoList = Vue.component('must-do-list', {
template: `
`
})
describe("MustDoList", () => {
it("MustdoItemを3つレンダーする", () => {
const wrapper = shallowMount(MustDoList, {
data() {
return {
mustdos: [
{ id: 1, text: "テストを書く" },
{ id: 2, text: "コードを書く" },
{ id: 3, text: "Qiitaに投稿する" },
]
}
}
})
assert(wrapper.findAll(".must-do").length, 3)
})
})
またやばい。MustDoItem
をレンダーしましょう。
Great!
最後に、MustDoItem
を使ってみましょう。
<script>
// ...
const MustDoList = Vue.component('must-do-list', {
data() {
return {
mustdos: mustdos
}
},
// ...
})
// ...
const mustdos = [
{ id: 1, text: "テストを書く" },
{ id: 2, text: "コードを書く" },
{ id: 3, text: "Qiitaに投稿する" },
]
document.addEventListener("DOMContentLoaded", () => {
new Vue({
el: "#app",
template: `
<must-do-list>
</must-do-list>
`
})
})
</script>
<div style="margin-left: 50px">
<div id="app"></div>
</div>
完了です。
まとめ
ツールは楽しいけど、たまにシンプルがいいですね。このindex.html
を使って色々なテストを書いてみてください。vue-test-utils
のドキュメントはこちらです。