next_study_241
第241章:テストを最低限入れる(重要画面だけ)✅🧪✨
卒業制作って、完成が近づくほど「うっかり壊れ」が増えがち…!😵💫 だからこの章は、**“ぜんぶ完璧に”じゃなくて「重要なところだけ守る」**がテーマだよ〜💖
今日のゴール 🎯✅
- 重要画面(重要導線)を3つ決める🗺️✨
- それぞれに対して 最低1本のテストを入れる🧪
- 「落ちたら直す」の流れを作って、安心して公開へ🚀🌈
1) まず「重要画面」だけ選ぶ🧠💡
おすすめは 3つに絞ること!多いと挫折する🥺💦
- 🧍♀️ ユーザーが一番通る導線(例:ログイン→一覧)
- 💎 あなたのアプリの“売り”機能(例:投稿、予約、検索)
- 💥 壊れたら詰むところ(例:保存、削除、決済っぽい処理)
図で考えるとラクだよ👇✨
2) 最小テストセットはこれでOK 🧁🧪
Next.js(App Router)だと、“画面の動き”をE2Eで守るのが強いよ💪✨
(特に async な Server Component はユニットテスト側の対応がまだ難しいので、E2E推奨って公式も言ってるよ〜)(Next.js)
おすすめ優先度はこれ👇
3) Playwright(E2E)を最低1本入れる 🕹️✨
3-1. 導入(最短)🚀
公式手順はこれでOK:npm init playwright でセットアップできるよ(Next.js)
npm init playwright@latest
途中の質問は、だいたいこんな感じでOK(迷ったらコレ)👇
- TypeScript: ✅
- tests フォルダ作成: ✅
- GitHub Actions: 好み(今はどっちでもOK)😌
ブラウザを自動操作するので、必要ならインストールも走るよ〜🧩
3-2. 重要導線テスト(例)を書く🧪✅
あなたの卒業制作に合わせて、**「一番大事な動線」**を1本だけ守ろう💖
例:トップ→ログイン→ダッシュボード表示(※文言は自分の画面に合わせてね!)
tests/e2e/critical-flow.spec.ts
import { test, expect } from "@playwright/test";
test("重要導線:ログインしてダッシュボードに入れる ✅", async ({ page }) => {
await page.goto("/");
// 例:ヘッダーの「ログイン」リンク
await page.getByRole("link", { name: "ログイン" }).click();
// 例:フォーム入力(ラベル名はあなたの画面に合わせて)
await page.getByLabel("メールアドレス").fill("test@example.com");
await page.getByLabel("パスワード").fill("password");
await page.getByRole("button", { name: "ログイン" }).click();
// 例:ログイン後の見出し
await expect(page.getByRole("heading", { name: "ダッシュボード" })).toBeVisible();
});
実行はこれ👇(Playwright導入時に scripts が入ってることも多いよ)
npx playwright test
💡うまくいかない時は、画面を見ながらが最強!
npx playwright test --headed
4) Vitest + React Testing Library(重要UI)を最低1本 🧁🧩
E2Eは“全体の安心”だけど、フォームやボタンの挙動は小さくテストできるとさらに安心☺️✨ Next.js公式の Vitest ガイドもこの組み合わせを前提にしてるよ(Next.js)
4-1. インストール(公式寄り)📦
npm install -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom vite-tsconfig-paths
npm install -D @testing-library/jest-dom @testing-library/user-event
vitest.config.mts(公式の形+ちょい足し)
import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [tsconfigPaths(), react()],
test: {
environment: "jsdom",
setupFiles: ["./vitest.setup.ts"],
},
});
vitest.setup.ts
import "@testing-library/jest-dom/vitest";
package.json にスクリプト(なければ追加)
{
"scripts": {
"test": "vitest",
"test:run": "vitest run"
}
}
4-2. 重要フォームのテスト(例)🧪✨
「空送信できない」「押したら呼ばれる」みたいな事故りやすい所を守ろう🛡️💕
例のコンポーネント(卒業制作の“入力フォーム”に置き換えてOK)👇
components/TodoForm.tsx
"use client";
import { useState } from "react";
export function TodoForm({ onAdd }: { onAdd: (title: string) => void }) {
const [title, setTitle] = useState("");
const canSubmit = title.trim().length > 0;
return (
<form
onSubmit={(e) => {
e.preventDefault();
if (!canSubmit) return;
onAdd(title.trim());
setTitle("");
}}
>
<label>
タイトル
<input
aria-label="タイトル"
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
</label>
<button type="submit" disabled={!canSubmit}>
追加
</button>
</form>
);
}
テスト👇
components/TodoForm.test.tsx
import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { TodoForm } from "./TodoForm";
describe("TodoForm", () => {
it("空のときは追加できない&入力したら追加できる ✅", async () => {
const user = userEvent.setup();
const onAdd = vi.fn();
render(<TodoForm onAdd={onAdd} />);
const button = screen.getByRole("button", { name: "追加" });
expect(button).toBeDisabled();
await user.type(screen.getByLabelText("タイトル"), "牛乳を買う");
expect(button).toBeEnabled();
await user.click(button);
expect(onAdd).toHaveBeenCalledWith("牛乳を買う");
});
});
実行👇
npm test
5) “最低限テスト”チェックリスト ✅🧡
最後に、ここまでできたら合格ライン〜!🎓✨
- 重要導線のE2Eが 1〜3本ある🧪
- 重要フォーム/重要ボタンのテストが 1〜3本ある🧩
- テストが落ちたら、まず
--headedとログで原因が追える👀 - “直したらテスト通る”の流れができてる🔁✨
必要なら、あなたの卒業制作の **画面一覧(例:/login /posts /posts/[id] など)を教えてくれたら、「どれを重要画面にするか」**と E2Eの1本目のシナリオをピッタリ一緒に決めて、サンプルもそれ用に作るよ〜😊💖