LoginSignup
2
1

【Test】チートシートとメモ (自分用)

Last updated at Posted at 2023-07-03

テスト実装例

  • コンポーネントには、ユーザー名を表示するテキスト要素、ユーザー名を変更するためのテキストフィールド、およびユーザー名を更新するボタンがあります。
  • テキストフィールドに新しいユーザー名を入力し、ボタンをクリックすると、テキスト要素のユーザー名が更新されます。

上記についてテストをしてみる

describe('UserProfileコンポーネント', () => {
  test('ユーザー名が正しく更新されるかどうかをテストする', async () => {
    // テスト用のモック関数を定義する
    const updateUsernameMock = jest.fn();

    // コンポーネントをレンダリングする
    render(<UserProfile username="John Doe" onUpdateUsername={updateUsernameMock} />);

    // テキスト要素を取得する
    const usernameElement = screen.getByText('John Doe');

    // テキストフィールドを取得する
    const textFieldElement = screen.getByLabelText('ユーザー名');

    // テキストフィールドに新しいユーザー名を入力する
    userEvent.clear(textFieldElement);
    userEvent.type(textFieldElement, 'Jane Smith');

    // 更新ボタンをクリックする
    userEvent.click(screen.getByText('更新'));

    // テキスト要素のユーザー名が更新されるのを待機する
    await screen.findByText('Jane Smith');

    // updateUsernameMockが適切に呼び出されたかを検証する
    expect(updateUsernameMock).toHaveBeenCalledWith('Jane Smith');
  });
});

メソッドの使い分け

  1. findByText

    • 非同期の更新を待つために使用します。
    • データの取得や非同期の処理が行われ、描画が完了するのを待つ必要がある場合に使用します。
  2. getByText

    • 描画されている要素を直接確認するために使用します。
    • 既存の要素がブラウザに描画されているかを確認する場合に使用します。
  3. queryByText

    • 要素の存在を確認するために使用します。
    • 要素が存在するかどうかを確認したい場合に使用します。

get 検索

検索方法 使い方
テキストの検索 getByText("テキスト") <div>テキスト</div>
ラベルによる検索 getByLabelText("ラベル") <label htmlFor="input">ラベル</label> <input id="input" />
CSSセレクタによる検索 container.querySelector(".my-class") <div class="my-class">要素</div>
属性による検索 getByAttribute("data-testid", "my-element") <div data-testid="my-element">要素</div>
テキストフィールドの値の検索 getByDisplayValue("テキスト") <input type="text" value="テキスト" />

find 検索

検索方法 使い方
findByText await screen.findByText(text) await screen.findByText("テキスト")
findByLabelText await screen.findByLabelText(text) await screen.findByLabelText("ラベル")
findBySelector await screen.findBySelector(selector) await screen.findBySelector(".my-class")
findByAttribute await screen.findByAttribute(attribute) await screen.findByAttribute("data-testid")
findByDisplayValue await screen.findByDisplayValue(value) await screen.findByDisplayValue("テキスト")

これらのfindByメソッドは、非同期操作が完了するまで待機し、要素を検索します。非同期操作が完了した後、要素が見つかるとPromiseが解決されます。要素が見つからなかった場合、指定されたタイムアウト時間を超過してもPromiseは拒否されます。

awaitを使用する。
useStateの処理のテストは大体findを使用する(setStateは非同期らしい)
これらのfindByメソッドは、テスト中に非同期操作が発生する場合や非同期でDOMの変更が行われる場合に役立ちます。

userEventの使い方

メソッド 説明
userEvent.click(element) 要素をクリックします。
userEvent.type(element, text) 要素にテキストを入力します。
userEvent.clear(element) テキスト入力要素の値をクリアします。
userEvent.selectOptions(element, value) セレクトボックスのオプションを選択します。
userEvent.tab() キーボードのTabキーを押します。

これらの操作は、テスト中にユーザーが実際に行う操作をシミュレートするために使用されます。例えば、テキストフィールドにテキストを入力したり、ボタンをクリックしたり、セレクトボックスのオプションを選択したりすることができます。

userEventを使用する際には、非同期操作やDOMの変更に対して適切な待機処理を組み合わせることが重要です。待機処理には、waitForactなどの適切な手段を使用して、操作が完了し、期待される結果が反映されるのを待つ必要があります。

これらの関数を組み合わせて使用することで、より実際のユーザーエクスペリエンスに近い形でテストを実行することができます。

以下に、共有していただいたマッチャーをテーブルにまとめました。

expect マッチャー

マッチャー 説明
toBeTruthy() 値が真の場合にパスします。
toBeFalsy() 値が偽の場合にパスします。
toBeNull() 値が null の場合にパスします。
toBeDefined() 値が undefined でない場合にパスします。
toBeUndefined() 値が undefined の場合にパスします。
toBeNaN() 値が NaN の場合にパスします。
toBeGreaterThan(value) 値が value より大きい場合にパスします。
toBeGreaterThanOrEqual(value) 値が value 以上の場合にパスします。
toBeLessThan(value) 値が value より小さい場合にパスします。
toBeLessThanOrEqual(value) 値が value 以下の場合にパスします。
toContain(item) 配列や文字列が item を含んでいる場合にパスします。
toMatch(pattern) 値が正規表現 pattern にマッチする場合にパスします。
toThrow(error) 関数が error をスローする場合にパスします。

テストの基本の形

describe("Review Page", () => {
  test("renders default page text", async () => {
    render(
      <Provider>
        <Page />
      </Provider>
    );

    // テキストが正しく表示されることを検証するアサーション
    const reviewText = screen.getByText("This is the default page for REVIEW");
    expect(reviewText).toBeInTheDocument();

    // 特定の要素が存在することを検証するアサーション
    const button = screen.getByRole("button", { name: "Submit" });
    expect(button).toBeInTheDocument();

    // クリックイベントをシミュレートして、期待される結果を検証するアサーション
    userEvent.click(button);
    const successMessage = await screen.findByText("Review submitted successfully");
    expect(successMessage).toBeInTheDocument();
  });
});

1. describeでテストスイーツ(グループ)を作成する
テストスイート名は、テストする機能やユースケースに関連したもの

describe("Calculator functionality", () => {
  // テストケースやアサーションを記述する
});

2. test関数でtestを定義
テストケース名は、テストの目的や期待される結果を反映するように具体的に命名

test("should subtract two numbers correctly", () => {
    // テストの内容を記述
  });

  test("should multiply two numbers correctly", () => {
    // テストの内容を記述
  });

3. renderでテストしたいコンポーネントをrenderする
テスト対象のコンポーネントをrender関数でレンダリングします

render(
 <Provider>
   <Page />
 </Provider>
);

4. アサーション(expect) を追加してテストの内容を検証する
レンダリング後のコンポーネントに対して、期待される結果を検証するアサーションを追加します。

// テキストが正しく表示されることを検証するアサーション
const reviewText = screen.getByText("This is the default page for REVIEW");
expect(reviewText).toBeInTheDocument();

// 特定の要素が存在することを検証するアサーション
const button = screen.getByRole("button", { name: "Submit" });
expect(button).toBeInTheDocument();

// クリックイベントをシミュレートして、期待される結果を検証するアサーション
userEvent.click(button);
const successMessage = await screen.findByText("Review submitted successfully");
expect(successMessage).toBeInTheDocument();

以上が基本的なテストを記述する順序🐇

Jotaiで管理したコンポーネントのテスト方法

コンポーネントをrenderする際にはProviderを使用すること

Jotaiの状態を参照したり更新したりするコンポーネントは、
適切な状態を提供するためにProviderコンポーネントが必要

describe("Sales test", () => {
  test("renders the Sales text", async () => {
    render(
      <Provider>
        <Sales />
      </Provider>
    );
});
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1