Reactで私たちは何をテストするべきか
私たちは何をテストするべきか
Reactフロントエンドは入力 が UI の操作なら最終出力も UI の状態でどっちもつかみどころのないものという、テストするには非常に不都合な宿命です。
純粋なロジック部分については、もちろんテストは必要だと思う。
でも個々の View コンポーネン トをテストしようとするなら、title という Props に 'Foo' という文字列を与えたら <title> タグの 中に Foo が表示される、みたいなテストになります。
そもそもプロダクトが大きく変わっていく局面で は膨大なテスト自体が変化への負債になりかねない。
フロントエンド開発において、何をテストするべきか、テストする労力に対してその効果が見 合うのかが明確じゃないせいだと思う
1. 設計者の意図通りに機能が実現されているかの確認
2. 新規に追加した全ての処理に破綻がないかの確認
3. 既存の機能を破壊していないかの確認
4. モジュラリティの確保
3 は TypeScript でコードを書いていることによる Null 安全性や型整 合性の確保によって、すでにある程度実現できていると思う。
ソフトウェアのバグで最も多いものが Null アクセスの例外だからね
4モジュラリティとは端的に言えば、不要な他からの依存が切れていて、他からの境界が自明になっ ている状態。つまりモジュールとして分離されていて、独立性が高く扱いやすいこと。
1、2のテストにいて今回やりましょう
Javascript のテスト用ツールはいろいろありますが、Facebook製の jest というテスト用フレームワークを使う。
インストール
$ npm init -y
$ npm install --save-dev typescript jest @types/jest ts-jest
それぞれ以下の通り変更&作成します。
package.json
{
// ...
"scripts": {
"test": "jest"
},
"jest": {
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
},
"globals": {
"ts-jest": {
"tsConfigFile": "tsconfig.json"
}
},
"testMatch": [
"**/__tests__/*.spec.+(ts|tsx|js)"
]
},
// ...
}
npm test で jest のテストを起動するようにコマンドを設定し、jestの設定値を追加しています。
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true,
"sourceMap": true
},
"include": [
"./src/**/*.ts"
]
}
tsconfig.json は Typescript のコードをコンパイルする際の設定値です。
今回は “src” 以下にコード、”__tests__” 以下にテストコードを配置します。
あとは生成された Jest の設定ファイル jest.config.js にて testEnvironment: "jsdom" に書き換える。
今回のテスト対象はブラウザ実行される JavaScript なので、jsdom を指定する。
React を テストするためのライブラリを導入する
React コンポーネントをテストするライブラリは複数あるが、公式が推奨している React Testing Library(RTL) を導入する。
yarn add -D @testing-library/react @testing-library/jest-dom
@testing-library/react ではコンポーネントのレンダリングや出力のために導入する。@testing-library/jest-dom では toBeInTheDocument() のような Jest の Matcher を拡張する。これによって、「Document 上に条件に合致するコンポーネントはレンダリングされているか」などの確認ができる。
テストツール選択理由、人気NO1
React Test Library の挙動を理解する
RTL の詳細な使い方は下記がわかりやすい。
https://qiita.com/ossan-engineer/items/4757d7457fafd44d2d2f
今回は自分整理して、テスト作業を説明致します。
手順ステップ1:Renderテスト
Renderとはデータ構造で記述された情報
次に、reactコンポーネントとテストの例を示します。
まず以下のようなテスト対象のコードを作成します
./src/Render.ts
import React from "react";
const Render = () => {
return (
<div>
<h1>React Testing Library 1</h1>
<input type="text" />
<button>Click1</button>
<button>Click2</button>
<p>App Design</p>
<span data-testid="copyright">@React</span>
</div>
);
};
export default Render;
次にテストコードを作成します。
./__tests__/Render.spec.ts
使い方は下記サイトご参考に
https://github.com/A11yance/aria-query#elements-to-roles
import React from "react";
import { render, screen } from "@testing-library/react";
import Render from "../Render";
describe("Rendering", () => {
it("Should render all the elements correctly", () => {
render(<Render />);
//全体テスト
//screen.debug();
//タグ存在テスト
//screen.debug(screen.getByRole("heading"));
//https://jestjs.io/docs/en/expect
//存在の場合はtoBeTruthy、無い場合toBeNullと予想します
expect(screen.getByRole("heading")).toBeTruthy();
expect(screen.getByRole("textbox")).toBeTruthy();
//同じタグ複数存在する場合getAllByRole
expect(screen.getAllByRole("button")[0]).toBeTruthy();
expect(screen.getAllByRole("button")[1]).toBeTruthy();
//内容をテストする場合
expect(screen.getByText("App Design")).toBeTruthy();
//異常内容をテストする場合
expect(screen.queryByText("エラーxxxx")).toBeNull();
//タグのID名テストする場合
expect(screen.getByTestId("copyright")).toBeTruthy();
//screen.debug(screen.getByText("App Design"));
});
});
プロジェクトのルートからnpx jestを実行すると、jestはあなたのテストを実行します。
この記事が気に入ったらチップで応援してみませんか?