Next.js 12+Storybook(CSF3.0) でStoryShotsを実現する
StoryShotsの概要
StoryShotsとは、コンポーネントの自動スナップショットテストを実現するツールで、Storybookに登録されているコンポーネントのUIが予期せず変更されていないかを確認することができます。
StoryShotsのセットアップ
Next.jsのアプリケーションにStorybook
が導入されていることを前提で進めます。
まだ導入されていない方は、以下参考にしてください。
-
package.json
に以下記述を追加する
{
"scripts": {
"dev": "next dev",
"build": "next build && next export",
"start": "next start",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
+ "storyshots": "jest --config ./jest.config.storyshots.js",
},
+ "resolutions": {
+ "react-test-renderer": "18.1.0"
+ },
}
※ 2022年10月現在、React 18を利用したアプリケーションでStoryShotsを実行するとTypeError: Cannot read properties of undefined (reading 'current')
というエラーが発生したので、依存関係のreact-test-renderer
のバージョンを指定することで解決しました。yarnを使っていない場合はnpm-force-resolutionsプラグインを使えば依存関係を固定することができます。
- 以下コマンドを実行し、必要なプラグインをインストールする
yarn add -D @storybook/addon-storyshots @testing-library/react @testing-library/jest-dom jest-environment-jsdom @storybook/testing-react
-
jest.config.storyshots.js
を作成する
const nextJest = require("next/jest");
const createJestConfig = nextJest({
dir: "./",
});
const customJestConfig = {
displayName: "storyshots",
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1", // tsconfig.jsonのcompilerOptions>pathsの定義に合わせてください
},
testEnvironment: "jest-environment-jsdom",
testMatch: ["<rootDir>/src/tests/jest.storyshots.ts"],
};
module.exports = createJestConfig(customJestConfig);
-
jest.storyshots.ts
を作成する(配置先は上記にあるtestMatchの設定に合わせる)
import initStoryshots, { multiSnapshotWithOptions } from "@storybook/addon-storyshots";
initStoryshots({
test: multiSnapshotWithOptions(),
});
multiSnapshotWithOptions
を設定すると、各コンポーネントごとにスナップショットファイルを生成できます。
StoryShotsを実行する
セットアップが完了したら、以下コマンドでStoryShotsを実行できます。
yarn storyshots
このようなログが表示されたら実行成功です✨
差分が発生している場合は、以下のようなログが表示されます。
意図的な差分の場合、下記コマンドを実行することでスナップショットを更新できます。
yarn storyshots -u
コンポーネント内でuseRouterをimportしている場合
StoryShotsを実行するコンポーネント内にuseRouter
が利用されている場合、実行時に下記のエラーが発生することがあります。
TypeError: Cannot read properties of null (reading 'pathname')
その場合、.storybook/preview.js
に以下記述を追加することで、useRouterのモックデータが設定され、本エラーを解決することができます。
+ import * as nextRouter from "next/router";
~中略~
+ nextRouter.useRouter = () => ({
+ route: "",
+ pathname: "",
+ query: { query: "" },
+ asPath: "",
+ basePath: "",
+ });
コンポーネント内でfetchを利用している場合
-
jest-fetch-mock
をインストールする
yarn add -D jest-fetch-mock
-
jest.setup.js
を作成する
require("jest-fetch-mock").enableMocks();
-
jest.config.storyshots.js
に以下記述を加える
const nextJest = require("next/jest");
const createJestConfig = nextJest({
dir: "./",
});
const customJestConfig = {
displayName: "storyshots",
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1",
},
testEnvironment: "jest-environment-jsdom",
+ setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
testMatch: ["<rootDir>/src/tests/jest.storyshots.ts"],
};
module.exports = createJestConfig(customJestConfig);
続きはこちら・・・
Discussion