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

Unit Testは「コンポーネントをテストする」
Reactの1コンポーネントごとにテストする感じ

Testing Library、Jest、Vitest。いまはVitestが流行りらしい

Integraton Testは統合テスト。単体テストが複数ある感じ。
2つのコンポーネントがきちんと組み合わさって機能してるかどうかを見るかんじ

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

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

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

なんでわざわざ失敗させる?
いきなり成功すると、今書いてるテストの内容が正しいテストの記述なのか、間違っているテストの記述なのかわからないから。

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%以下の時にどの行で発生しているか見れる

一般的には80%超えてたらよさそう

getByRole
は重複するとエラー出る

Roleはここ参照する

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

どういう優先度にしたらいいかはドキュメントの優先度を参照する

getByTestId
はあとから要素変えたりするときに便利。
たとえば、p
タグから h2
タグに変えるときに
<p data-testid="custom-element">テキスト</p>
で、data-testid
のテストを通す。
そのあと、p
-> h2
に変える。
そのあと優先度の高いテストに変えたりする。(最終的に getByTestId
は消す、くらいのきもち)

findBy
は非同期処理をする時に使う

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

ユーザーインタラクションもテスト可能

フェイクデータとってこれる

-
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時点)

ビジュアルリグレッションテスト