Zenn
Open42

Udemy見ながらテスト入門メモ

ちあきちあき

Unit Testは「コンポーネントをテストする」

Reactの1コンポーネントごとにテストする感じ

ちあきちあき

Integraton Testは統合テスト。単体テストが複数ある感じ。

2つのコンポーネントがきちんと組み合わさって機能してるかどうかを見るかんじ

ちあきちあき

E2Eテストは「最初から最後までちゃんと動くかどうかのテスト」
本当にユーザーが使うみたいにテストする

ちあきちあき

テストはStatic < Unit < Integration < E2E の順にコストが上がっていく。
コストが高くなるにつれ、失敗したらどこが失敗したかが見づらくなっていく。
が、正常に動く信頼度がどんどんあがっていく。(当たり前)

ちあきちあき

なんでテストする?

  • 開発者の実装の自信をつける
  • バグの早期発見になる
  • 実装段階でコンポーネントの責務を分離しようという意識ができる
ちあきちあき

TDDとは

  1. 間違った(未実装の機能の)テストを書く(わざと失敗させる)-> レッドテスト
  2. テストが成功するように機能を実装する -> グリーンテスト
  3. リファクタリングする ※オプション。リファクタリング不要ならいらない
ちあきちあき

なんでわざわざ失敗させる?

いきなり成功すると、今書いてるテストの内容が正しいテストの記述なのか、間違っているテストの記述なのかわからないから。

ちあきちあき

Jestのwatchモードについて

Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press o to only run tests related to changed files.
 › Press q to quit watch mode.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press Enter to trigger a test run.
ちあきちあき
  • a -> 全てのテストを実行
  • f -> 失敗したテストだけ実行(大規模になってくると有用)
  • o -> 直近に変更されたファイルだけテスト実行
  • q -> watchモード終了
  • p -> ファイル名でフィルタリング
  • t -> テスト名でフィルタリング(英語じゃないとだめそう)
ちあきちあき

カバレッジテスト

Stmts -> 全てのステートメント(命令)に対してテストできているか
Branch -> if文などの条件分岐に対してテストできているか
Funcs -> 関数に対してテストできているか
Lines -> 行ごとに対してテストできているか
Uncoverd Line -> 100%以下の時にどの行で発生しているか見れる

https://jestjs.io/ja/docs/cli#--coverageboolean

ちあきちあき

getByRolegetByLabelText なにがちがう?

getByRole はロールの属性と name で指定したラベルが存在しているかどうか
getByLabelText はラベルに指定のテキストがあるかどうか

ちあきちあき

getByTestId はあとから要素変えたりするときに便利。

たとえば、p タグから h2 タグに変えるときに

<p data-testid="custom-element">テキスト</p>

で、data-testidのテストを通す。
そのあと、p -> h2 に変える。

そのあと優先度の高いテストに変えたりする。(最終的に getByTestId は消す、くらいのきもち)

ちあきちあき
screen.debug();

でDOM要素を確認できる。 findBy と組み合わせたら、書き換え前・書き換え後のDOMの状態を見れる

ちあきちあき

MSW はなんで必要なのか?

たとえば、バックエンドのAPI開発が終わってなくてエンドポイントが叩けないときに、フロントエンド側で擬似的にAPIを作成してテストするためにつかう。

ちあきちあき
  • toBe -> 期待値がテスト対象の値と全く同じであることを検証する
  • toEqual -> オブジェクトや配列などを検証する
  • not -> 期待値が一致しないことを検証する
  • toThrow -> 関数がエラーをスローすることを検証する
    • expectに直接渡さず、無名関数でラップする必要がある。(テスト対象の関数でエラーが発生したらマッチャー関数が呼ばれる前に関数が停止する)
ちあきちあき

jest.fn() は何も処理を行わない新しいモック関数を生成する。
何らかの処理を行わせたいなら、引数にコールバック関数を渡す。

const mockFunc = jest.fn(() => "Hello mock");
ちあきちあき

mockImplementation でも可能。
始めは空のモック関数で実装しておいて、あとから追加したりもできる。

it("mockImplementation", () => {
    const mockFunc = jest.fn();
    mockFunc.mockImplementation(() => "Hello mock2");
    expect(mockFunc()).toBe("Hello mock2");
});
ちあきちあき

単体テストに適した3つのパターンをもとに書く

Arrange - 準備
Act - 実行
Assert - アサート

ちあきちあき
it("モック関数が呼び出される", () => {
    // Arrange
    const mockFunc = jest.fn();
    // Act
    mockFunc();
    // Assert
    expect(mockFunc).toHaveBeenCalled();
});

こんなかんじ

ちあきちあき

UIテストの検証内容

  • 正しい出力の描画
  • ユーザーインタラクションの反応(クリックしたーとかテキスト入力したーとか)
  • コンポーネントのライフサイクル(状態変化時に正しく更新されるか)
  • propsの正確な伝達できているか
  • 子コンポーネントの描画が正確に、期待される条件下で描画されるか
ちあきちあき

waitFor関数を使った非同期処理のテストは、実行時間が長くなりがち。
アプリケーション開発のときは、「このテストは必要か?」「モック化する」などよく検討する

ちあきちあき

Storybookでのテストはモックが利用できない(v7時点)

作成者以外のコメントは許可されていません