Testing Libraryで<input type="text">に対するテストケースを書く

テキスト入力を行う<input type="text">1コンポーネントはWebアプリケーション開発を行う場合ほぼ必須となる。このテストケースの記載方法を覚えておくとあらゆる面で応用が効くためTODOを挙げて記載方法を確認していく。

TODO

  • 苗字の入力フォームと名前の入力フォームが存在する
  • フォームに値が入っている場合は「こんにちは、"苗字フォームの入力値" "名前フォームの入力値"さん!」と表示される
  • 片方のフォームに値が入っている場合は「こんにちは、"フォームの入力値"さん!」と表示される
  • 両方のフォームが空の場合「苗字か名前を入力してください」と表示される

コンポーネントの実装は次のようになっている。

import React, { useState } from "react";

interface UserInfo {
  lastName: string;
  firstName: string;
}

export default function NameForm() {
  const [form, setForm] = useState<UserInfo>({
    lastName: "山田",
    firstName: "太郎",
  });

  const handleForm = (e: React.ChangeEvent<HTMLInputElement>) => {
    setForm({
      ...form,
      [e.target.name]: e.target.value,
    });
  };

  return (
    <form>
      <div>
        <label htmlFor="lastName">苗字</label>
        <input
          id="lastName"
          name="lastName"
          type="text"
          onChange={handleForm}
          value={form.lastName}
        />
      </div>
      <div>
        <label htmlFor="firstName">名前</label>
        <input
          id="firstName"
          name="firstName"
          type="text"
          onChange={handleForm}
          value={form.firstName}
        />
      </div>
      <p>
        こんにちは、{form.lastName} {form.firstName}さん!
      </p>
    </form>
  );
}

テキスト入力フォームの値を取得する

フォームの値はtoHaveValue()で取得できる。<input>要素の取得方法はgetByRoleを使い、roleにtextboxを指定すれば良い。

describe("初期表示に関するテスト", () => {
  it("苗字のフォームには山田と入力されている", () => {
    const content = render(<StateForm />);
    expect(content.getByRole("textbox", { name: "苗字" })).toHaveValue("山田");
  });
});

getByRoleにformを指定すると動かない

テキスト入力フォームに関するテストを書こう!valueを取得するのだからラベルでキストではなく<input>要素を取得しよう!フォームだからroleはformだろう、という形でgetByRoleの指定にformを指定したくなってしまう。

it("苗字のフォームには山田と入力されている", () => {
  const content = render(<StateForm />);
  expect(content.getByRole("form", { name: "苗字" })).toHaveValue("山田");
});

しかし、この状態でテストを書いても「要素が存在しない」エラーとなって失敗する。

> reactjs-sandbox@1.0.0 test
> node scripts/test.js --watchAll=false src/component/Form/NameForm.test.tsx

 FAIL  src/component/Form/NameForm.test.tsx
  初期表示に関するテスト
    ✕ 苗字のフォームには山田と入力されている (49 ms)

  ● 初期表示に関するテスト › 苗字のフォームには山田と入力されている

    TestingLibraryElementError: Unable to find an accessible element with the role "form" and name "苗字"

    Here are the accessible roles:

formはフォーム要素<form>2のroleなので、テキスト入力フォームではないからである。 要素が見つからない場合、MDNなどでroleを確認すると間違いに気づきやすい。