何もテストしていないコンポーネントテストを改善する

今からの話は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の 一般的なヒントを読んで欲しい。

vue-test-utils.vuejs.org

代わりに、コンポーネントのパブリックインターフェイスを検証するテストを作成し、内部をブラックボックスとして扱うことをお勧めします。単一のテストケースでは、コンポーネントに提供された入力(ユーザーのやり取りやプロパティの変更)によって、期待される出力(結果の描画またはカスタムイベントの出力)が行われることが示されます。

つまり、大事なのは 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が falsetruefalseになったときをテストした方が良いかもしれない。リセットの挙動があるコンポーネントは「元に戻るパターン」もテストしておいた方が良い。

という感じで、最近は意味のないテストを書かないようにするため次のことを気をつけている。

  • データの状態で見た目が変わるところにテストを書く
  • データが変わったとき見た目が変わるのか?
  • 初期状態に戻るパターンはあるか?

もっと鍛錬して意味のあるテストがうまく書けるようになりたい。


  1. こんな設計は微妙!とか今はなし。アプリ開発なしで例考えるのむずくないですか