はじめに
Vue.jsを使うのもなんか慣れてきたし、AtomicDesignに基づいたComponentも作れるようになってきたな…
せや!そろそろ自動テストやってみるか!
てなことで、AtomなComponentを自動テストしてみた記事です。
AtomicDesignとは
Javascriptのコンポーネント指向なフレームワークをどう設計していくかの設計思想です。
コンポーネントを5つの構造に分け、それぞれの役割を明確に決め、再利用や可読性を上げます。
- Atom
- Molecules
- Organisms
- Templates
- Pages
Atomが最小のコンポーネントとなり、下にいくほど規模が大きくなっていくイメージです。
(#AtomicDesignについては、Qiita含めたくさん記事があるので詳しくは省略します)
今回は、その中でAtomを対象にしたいと思います!
テスト環境
- Vue.js
- vue-test-utils
- Jest
vue-cliのプロジェクト作成時に、Manualを選びTestを有効化し今回はJestを選択しました。
やってみよう
ということで、ぱぱっと以下のようなComponentをテスト自動してみましょう
<template>
<input
type="text"
v-model="inputText"
>
</template>
<script>
export default {
name:"Atom-input",
props:{
value:{
type:[String, Number]
}
},
computed:{
inputText:{
get:function(){
return this.value
},
set:function(value){
this.$emit("change",value)
}
}
}
}
</script>
Atomのルールとして、状態やデータを持ってはならないというのがあるため、dataの記述がないコンポーネントとなります。
上位からpropsでvalueの値を受け取り、それをcomputedのsetter/getterを経由しv-modelでinputに紐づけております。
propsをそのままv-modelでinputにバインディングしたいところですが、Vueのルールとして単方向データフローがあります。
propsを子コンポーネントが変更することはそのルールに違反することとなりますので、子から直接propsの値を変更することはできません。
そこで、computedのsetter/getterを使うことで、v-modelが値を呼び出すときはgetterでpropsの値を取得、変更はsetterで親への通知イベントを行っています。
参考にさせていただいた記事
- Vue公式:フォーム入力バインディング
- Vue公式:算出プロパティとウォッチャ
- v-modelにオブジェクトをバインディングする場合のコンポーネント実装を考える
- Vue.jsのv-modelを正しく使う
テストを作ってみよう
1つのコンポーネントで行うべきテストケースは色々ありますが、今回は1つに絞ります。
テストケースとしては、
入力した値が親に返されてくるかをテストしてみたいと思います。
describe('AtomInputText.vue',()=>{
it('入力した値が親に返されてくるか',()=>{
const wrapper = mount(Input);
const value = 'valueだよ';
const input = wrapper.find('input[type="text"]');
input.setValue(value)//v-model on change
expect(wrapper.emitted().change[0][0]).toBe(value);
});
});
内容としてはとてもシンプルです。
対象コンポーネント内にあるinputを見つけて、それに対してsetValueで値をセットしています。
setValue自体が、セットとinputイベントを同時に行うAPI的な書き方ですので、1行で済ますことができます
Vue Test Utils : setValue
setValueを使わずに書くとしたら、
input.setValue(value)//v-model on change
これが
input.element.value = value
input.trigger('input')
こういう風な書き方となります。
setValueでinputが行われるため、v-model="inputText"のから算出プロパティのsetterが呼び出されます。
そしてsetterには$emitがあるため、引数の値を親にイベントで伝えております。
なのでテストコード側では最後にemittedでやってきた値を見ることで、
正しく入力された値がやってくるかのチェックができます。
上の方にも書きましたが、再利用性を高めるためにAtomやMoleculesでは状態を持ってはいけないため、
テストコード側でも入力した値をテストするために、dataなどを確認するのではなくemittedで確認しています。
やってみた感想
書いてみるとすごく短くて記事としてもシンプルなものとなりましたが、知らずにやろうとしたら割と詰まったので記事にしてみました。
テストケースを書くことで、データの流れやイベントなどをより意識しコーディングするようになったので、テスト自動化は早めに着手するのがいいなと感じました。