『フロントエンド開発テスト入門』読みつつキャッチアップ

第1章と第2章は読み直したのでスキップ
社内でのテストを考える上ではまた読み返した方がいいかも

第3章 はじめての単体テスト

第4章 モック

第5章 UIコンポーネントテスト
セットアップとしてjsdomやtesting-libraryを導入しているが、storybookがあれば不要になったはず
testing-libraryが同伴されてるし、vitestがデフォルトになったから(たぶん)

これで環境作る

表示要素はcanvasElementで確認すれば良さそう

vitestのbrowser modeも試したい

renderに必要っぽい

うーん、Form.test.tsxを作成してBrowser modeでテストさせようとすると、vitest.config.jsをどうやって書けばいいのかよくわからない
*.test.tsx
のみを対象にBrowser modeテストを書く?

play functionのみで書こうとすると、vitestの能力が制限されそうな気がするけどそんなことない?
こういうテストをどうやって書いたらいいんだろう
(そもそもこのテストいらない気もするけど)

よくわからんけどvitest.config.js
をclaudeに直してもらったらできたっぽい
includeとexcludeで指定してみた

snapshotテストはあんまり意味ない気がするからVRTに寄せたい(けど後で出てくるからいいや)

play functionにテスト書き始めるとstoriesファイルがごちゃつく気がするな
まあ仕方ない(?)
NoItemとかの表示とテストが紐づいてるのはわかりやすくていい気もする

fetch関数をmockしようと思ったけど、mswじゃないとうまくmockできない?
vitest単体のモックとstorybookがからんだ時のモックの違いがよくわからんなぁ

5.6 ユーティリティ関数を使用したテスト
formのテスト、buttonのtype="submit"
にしてるとNo Preview?みたいな画面に飛んでしまうのでうまくテストできない
5.7ではsubmitでもうまくいくからなんかよくわからなくて治したい

5.7 非同期処理を含むUIコンポーネントテスト
fetchのモック部分はMSWで代用することにした
こっちはformのbuttonTypeがsubmitじゃないと動かないので、変な実装になってしまった

改めて読み直してたけど、mountとかあるんだ

mockもあるやん

上の記事をちゃんと読むのが良さそう

preview.tsに登録したらmockedが使えるようになった

いや全てのStoryで特定の関数がモックされるの辛いな、これはダメだ
(そういうシチュエーションはあるかもだけど今回はちょっと違った)

ひとまず、対象の関数はモックして、その処理に近い形でエラーハンドリングを扱えるようにした
なぜかValidationErrorのインスタンスはstoryの中で扱えなかった(ESMがどうの、みたいな話っぽい?よくわからん)

browser modeはスクショをとってるからか遅い気がする
あと、スクショってコミットしないんだっけ?

第6章 カバレッジレポートの読み方

今こんな感じ

- Stmts(命令網羅率)
- 全てのステートメントが少なくとも1回実行されたか
- Branch(分岐網羅率)
- 全ての分岐条件が少なくとも1回通過したか
- Funcs(関数網羅率)
- 全ての関数が少なくとも1回呼び出されたか
- exportされてるが使われてない、など(knipでもいいけど)
- Lines(行網羅率)
- 全ての行を少なくとも1回通過したか

Vitest UIなんてあったっけ、かっこいい

カバレッジ率、すべて100%以外だと割れ窓になる気がするけど実際は複雑な理由で難しいんだろうな

Claude Codeに100%にしてもろた
数秒の出来事

6章までの感想
ユニットテストの章が終わったので感想
- 以前は環境構築の大変さで心折れてた気がするけどStorybookやVitestのおかげで全然楽
- jestとかjsdomとかhappydomとか、そこらへんでつらみがないのがよい
- 困ったらClaude Codeに聞けばほぼ解決できる
- モック周りは全然ダメだったけど...
- モック周りはStorybookだと小回りきかない気もするけど、別にmswや今の機能でそんなに困らないかな?
- ストーリーごとに細かくモック制御したいけどビルド時に何やら解決してるから無理っぽい
- その点、vitestで書いて、browser modeとかの方が今までの書き方できて楽ではある
- Browser Modeでテストは安心だけど、ちょっと遅い(ひとつのコンポーネントテストで数秒かかった)
- 素のまま使ってたらスクショとってくれてたけどそのせいかな、設定でスクショ抑制する?
- storiesファイルがごちゃつくのはどうなんだろう
- 単純にカタログとしてみたい時、play functionが先に動くとちょっと邪魔な気もする
- スモークテストとして壊れてないことが確認できるからいいんだろうけど...何か方法あるのかな

Agentのおかげでテスト書くコストはほぼなくなった気がする
ちゃんとパターンのレビューさえ出来ればかなり楽できる
(今回はRuleとか書かずに雑に指示してたけど、それでもまあまあよかった)

7章以降のための環境構築
App routerとか使いたいので自前で環境作り直す
気まぐれでパッケージマネージャーはbun、あとbiomeの組み合わせ
// nextjs
bun create next-app@latest . --yes
// 動作確認
bun dev
// biome導入
bun add --dev --exact @biomejs/biome
// vitest browser mode
bunx vitest init browser

7章 Webアプリケーションの結合テスト
ひとまずはコピペしたコンポーネントに対してテストを書く(というかClaude Codeに書いてもらう)
困っても雑にCalude Codeに聞くと解決してくれてうれしい、テストのつらみがだいぶ減ってる


import Link from 'next/link'
ってモックしなくていいの?普通にテストとして書いてあるな
けどリポジトリにこのコードはなさそう

手元で失敗したから聞いたらclaude codeはこういうコードを吐いた
丸っと書き換えちゃってるからダメな気がする?
あとnext/linkのせいでcoverageのbranchが50%になってしまう
// Mock Next.js Link component
vi.mock("next/link", () => {
const MockedLink = ({
children,
href,
...props
}: {
children: React.ReactNode;
href: string;
[key: string]: unknown;
}) => (
<a {...props} href={href}>
{children}
</a>
);
return {
__esModule: true,
default: MockedLink,
};
});

server componentのテスト

Switchの実装で遭遇した
role="switch"
のときはaria-checked
が必要とのこと

userEventはcontextから

エイリアスの解決

useUploadImageのテスト、色々モックするものが多くて大変
S3関連は読むのめんどくさかったからURLだけ渡したらいい感じにしてくれた

vitestでnext/routerとnext/linkをいい感じにモックするにはどうしたらいいんだ

ちょっと古いか

よくわからんけどモックしてみてもらった、これあってんのかな
テストは通るようになった

⏺ Next.jsのルーターをモックするには、next/navigationのuseRouterをモック
する方法が一般的です。
import { vi } from "vitest";
// Next.js navigation hooks をモック
const mockPush = vi.fn();
const mockReplace = vi.fn();
vi.mock("next/navigation", () => ({
useRouter: () => ({
push: mockPush,
replace: mockReplace,
pathname: "/",
query: {},
}),
}));
ただし、Linkコンポーネントのクリックテストの場合は、実際にナビゲーシ
ョンが発生するかではなく、正しいhrefが設定されているかをテストする方
が実用的です:
test("リンクが正しいURLを指している", async () => {
const screen = render(<Heading />);
const link = screen.getByRole("link");
await expect.element(link).toHaveAttribute("href", "/");
});
どちらのアプローチがお好みですか?

(テストの内容を理解してないけど)
このテストを実装しようとしたら山ほどモックするものがあって大変、全部Agentにやってもらってるけど