今からの話はVue Test Utilsで書かれたコンポーネントテストについての話です。でも観点は他のテストライブラリでも一緒かなと思います。
今まで職場を転々としてきたが、今の職場は初めて「フロントエンドのテスト環境がある」職場だった。コンポーネントへのテストは「少しだけある」状態だったが、「テストはあるけど中身がない」ものもいくつかあった。過去の自分への指摘(そもそも最初は全く書けなかったし…)も兼ねて残しておく。
次のようなコンポーネントがあったとする 1。
- Props
checked:true
のときはチェックアイコン表示 - Props
checked:false
のときはチェックアイコン非表示 - デフォルト値は
false
をセットしておく
このコンポーネントにはテストがあった。蓋を開けるとこんな感じで実装されていた。
describe("Propsに関するテスト", () => { it("デフォルト値がfalseであることをテスト", () => { const checked = false; const wrapper = shallowMount(TestComponent, { propsData: { checked }, }); expect(wrapper.props().checked).toBe(false); }); });
…確かにテストはある。デフォルト値が設定できているかテストされている。でも、Vue Test Utilsの 一般的なヒント
を読んで欲しい。
代わりに、コンポーネントのパブリックインターフェイスを検証するテストを作成し、内部をブラックボックスとして扱うことをお勧めします。単一のテストケースでは、コンポーネントに提供された入力(ユーザーのやり取りやプロパティの変更)によって、期待される出力(結果の描画またはカスタムイベントの出力)が行われることが示されます。
つまり、大事なのは Props値に応じてコンポーネントの見た目がどう変わるか
という点ではないだろうか。デフォルトがfalse
であれば、初期描画はfalse
の見た目だよね、という点をテストするべきなんじゃないだろうか。
こういうテストの方が実際の動作に沿っていると思う。find
の部分は実際の部品に合わせて置き換えてもらいたい。
describe("Propsに関するテスト", () => { it("初期描画時ではチェックアイコンが非表示になっていること", () => { const checked = false; const wrapper = shallowMount(TestComponent, { propsData: { checked }, }); // チェックアイコンのidを探索し、存在しないことを確かめる expect(wrapper.find('#check-icon').exists()).toBe(false); }); });
そうするとPropsが途中でtrue
になったパターンが欲しくなる。
describe("Propsに関するテスト", () => { const checked = false; const wrapper = shallowMount(TestComponent, { propsData: { checked }, }); it("初期描画時ではチェックアイコンが非表示になっていること", () => { // チェックアイコンのidを探索し、存在しないことを確かめる expect(wrapper.find('#check-icon').exists()).toBe(false); }); it("checked:trueに変化したとき、チェックアイコンが表示されること", async () => { // Props値の更新 await wrapper.setProps({ checked: true }) // チェックアイコンのidを探索し、存在することを確かめる expect(wrapper.find('#check-icon').exists()).toBe(true); }); });
物によってはPropsが false
→ true
→ false
になったときをテストした方が良いかもしれない。リセットの挙動があるコンポーネントは「元に戻るパターン」もテストしておいた方が良い。
という感じで、最近は意味のないテストを書かないようにするため次のことを気をつけている。
- データの状態で見た目が変わるところにテストを書く
- データが変わったとき見た目が変わるのか?
- 初期状態に戻るパターンはあるか?
もっと鍛錬して意味のあるテストがうまく書けるようになりたい。
-
こんな設計は微妙!とか今はなし。アプリ開発なしで例考えるのむずくないですか↩