はじめに
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
で確認しています。
やってみた感想
書いてみるとすごく短くて記事としてもシンプルなものとなりましたが、知らずにやろうとしたら割と詰まったので記事にしてみました。
テストケースを書くことで、データの流れやイベントなどをより意識しコーディングするようになったので、テスト自動化は早めに着手するのがいいなと感じました。