Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
AIのためのテスト戦略 〜TDDが難しいフロントエンド開発でのアプローチ〜
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ディップ株式会社
PRO
October 06, 2025
Technology
60
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
AIのためのテスト戦略 〜TDDが難しいフロントエンド開発でのアプローチ〜
ディップ株式会社
PRO
October 06, 2025
More Decks by ディップ株式会社
See All by ディップ株式会社
_型ガードしたのにnullable_から卒業する.pdf
dip_tech
PRO
0
54
はじめての環境構築!デプロイ〜Docker基礎を学べるワークショップ!
dip_tech
PRO
0
49
【TSKaigi2026登壇資料】決定論的な型チェックへ Go 製コンパイラによる10倍速の裏側で stableTypeOrdering から見える並列化への挑戦
dip_tech
PRO
2
470
【TSKaigi2026登壇資料】バイトル」のTypeScriptリニューアル — 積み上がったレガシーとパフォーマンスに挑む現在地
dip_tech
PRO
1
890
【新卒研修】ライブデモ + compose.yaml読解_講義資料
dip_tech
PRO
0
420
【ディップ|26年新卒研修資料】OpenAPI/Swagger REST API研修
dip_tech
PRO
0
570
【ディップ|26年新卒研修資料】Docker_ハンズオン研修
dip_tech
PRO
0
520
【ディップ|26年新卒研修資料】TDD実装演習
dip_tech
PRO
0
580
ハッカソンや個人開発で何作る? テーマ発見〜アイデア発想ハンズオン! 技育CAMPアカデミア
dip_tech
PRO
0
110
Other Decks in Technology
See All in Technology
PLATEAU で バーチャル花火大会
tatsuya1970
0
170
【GCC2026】大規模言語モデルを活用した内製検索サービスの社内展開や業務活用
bandainamcostudios
PRO
0
260
My broken English still works: speaking at global OSS events
naruoga
0
110
Breaking the Seal: Static Deobfuscation of Compiled V8 JavaScript Bytecode Malware
hshrzd
0
860
モバイルアプリ開発概論2026
recruitengineers
PRO
6
660
制約理論(ToC)入門 2026版
recruitengineers
PRO
8
2.6k
Reference-Free Image Quality Assessment for Virtual Try-On via Human Feedback
zozotech
PRO
0
630
同じWAFが、攻撃の“形”は弾く── 正当な“形”の不正は通す
kuroneko13
0
240
ホームラボ紹介
y_sera15
0
210
ラジオの科学
frievea
0
350
FPGAが実現する遠方宇宙の高空間分解能天体撮影 -大型地上望遠鏡の視力を補正する「補償光学」とは?-
komei_mt
0
430
その“隠したつもり”が命取り ── 自前と平文をやめて「正解」に委ねる
kuroneko13
0
130
Featured
See All Featured
AI: The stuff that nobody shows you
jnunemaker
PRO
9
920
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
GraphQLとの向き合い方2022年版
quramy
50
15k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
The SEO identity crisis: Don't let AI make you average
varn
0
530
Deep Space Network (abreviated)
tonyrice
0
260
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
210
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
45k
Accessibility Awareness
sabderemane
1
180
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
170
The Spectacular Lies of Maps
axbom
PRO
1
920
Transcript
AIのためのテスト戦略 〜TDDが難しいフロントエンド開発でのアプローチ〜 2025/10/04 横山 隼 ScrumMatsuri 2025
自己紹介 • ディップ株式会社 • 2022年新卒入社 • フロントエンドエンジニア 横山 隼
みなさん、AIコーディングはされていますか?🤔
されていますよね😌
最近は、AIコーディングが当たり前になってきました
開発スピードは爆発的に速くなりました 🚀
とはいえ、まだまだ指示したことと違うことするときがある🤔
関係ないところまで修正に手を出して、
関係ないところまで修正に手を出して、 エラーが出て、
関係ないところまで修正に手を出して、 エラーが出て、 違う治し方して、
関係ないところまで修正に手を出して、 エラーが出て、 違う治し方して、 そうじゃないってなることがある
今回は、AIに開発を任せて、 開発スピードを落とさずにガードレールとなるような
フロントエンドテストの取り組み 5つ紹介します
抽象的な大きな取り組みから、 具体的なテクニック的な話まで含まれます
チーム状況 🧰 技術スタック TypeScript, React Router v7 🧠 AIコーディング JiraやFigmaをMCP経由で
Claude Code に取り込み、実装させる チーム人数 エンジニア3人 少人数ながら AIを活用してスピードと品質の両面を追う
FEがBEと通信する層を厚くテストする
FEがBEと通信する層を厚くテストする • ビジネス上の重要なロジックが集中しやすい層なので 厚くテストする • テスタブルにするために なるべく純粋なTypeScript関数になるようにする
私のチームではReact Router の Loader/Action関数をBFF層として データ取得、整形、送信、バリデーションなどをしている テストケース抜粋 • 名前・メール・電話番号を正しく入力すると、入力内容が返されること • 応募確認画面で閲覧中に求人が締切になったら、応募エラーになること
• 応募ボタン連打しても、二重送信されないこと Loader/Actionをカバレッジ 100%になるように書いている
StorybookのcomposeStoriesで 共通コンポーネントをテストする
「フロントエンドのテストを書いていこう!」とすると よくあることとして...🤔
it("'Hello World' のテキストが表示されること ", () => { render(<Greeting text={"Hello World"}
/>); expect(screen.getByText("Hello World")).toBeInTheDocument(); }); export function Greeting({ text }: GreetingProps) { return <p>{text}</p>; } Propsで渡されたテキストを表示するコンポーネントに対して、 テキストが表示されること ➡ 効果の低いテストを過剰に書いてしまう
一方で🤔
➡ ユーザー操作を含むテストは再現するのが難しく、コストが高い // テスト上でスクロール操作ができないので、スクロール量を上書きする const setScrollY = (y: number) =>
{ Object.defineProperty(window, "scrollY", { configurable: true, value: y, }); window.dispatchEvent(new Event("scroll")); }; it("スクロール量が閾値を超えたらナビゲーションバーが表示される", () => { render(<Navbar />); expect(screen.queryByTestId("navbar")).toBeNull(); setScrollY(120); expect(screen.getByTestId("navbar")).toBeInTheDocument(); });
すべてのコンポーネントに対して、 テストしようとすると過剰になりがち でも、効果が高いインタラクティブな挙動を テストするのはコストが高い
だからこそ、アプリ全体で繰り返し使われる 共通コンポーネントに絞ってテストする
だからこそ、アプリ全体で繰り返し使われる 共通コンポーネントに絞ってテストする ➡ StorybookのcomposeStoriesでテストする
📚 composeStories・・・ Storybookのストーリーをテスト環境で利用できる仕組み const meta: Meta<typeof Button> = { title:
"Components/Button", component: Button, args: { label: "Click Me" }, }; export default meta; type Story = StoryObj<typeof Button>; export const Primary: Story = { args: { disabled: false }, }; export const Disabled: Story = { args: { disabled: true, label: "Disabled" }, }; it("Primary: ~~~~", async () => { render(<Primary onClick={onClick} />); // 略 expect(onClick).toHaveBeenCalledTimes(1); }); it("Disabled: ~~~~", async () => { render(<Disabled onClick={onClick} />); // 略 expect(onClick).not.toHaveBeenCalled(); }); Storybook テスト
📚 composeStories・・・ Storybookのストーリーをテスト環境で利用できる仕組み const meta: Meta<typeof Button> = { title:
"Components/Button", component: Button, args: { label: "Click Me" }, }; export default meta; type Story = StoryObj<typeof Button>; export const Primary: Story = { args: { disabled: false }, }; export const Disabled: Story = { args: { disabled: true, label: "Disabled" }, }; it("Primary: ~~~~", async () => { render(<Primary onClick={onClick} />); // 略 expect(onClick).toHaveBeenCalledTimes(1); }); it("Disabled: ~~~~", async () => { render(<Disabled onClick={onClick} />); // 略 expect(onClick).not.toHaveBeenCalled(); }); Storybook テスト
composeStoriesを使うことで... • ストーリーの更新することでテストも同時に更新され、 ストーリーとテストに乖離が起きない • ストーリーごとに「本番と近い環境」で UI を再現できる
composeStoriesを使うことで... • ストーリーの更新することでテストも同時に更新され、 ストーリーとテストに乖離が起きない • ストーリーごとに「本番と近い環境」で UI を再現できる ➡ 共通コンポーネントに絞ってテストする
AAAパターン
Arrange(準備), Act(実行), Assert(検証)の 3つセクションに明示的に分けた構成でテストを書く it('2つの正の数を正しく足し算できること', () => { // Arrange
(準備): const num1 = 5; const num2 = 3; const expectedSum = 8; // Act (実行): const actualSum = add(num1, num2); // Assert (検証): expect(actualSum).toBe(expectedSum); });
AIコーディングするにあたって、細かなルールで書き方を制限して、 表現の自由度を狭めてあげる
テストケース名は ユーザー/ビジネス視点で記述する
it('応募ボタンを押すと確認画面に進むこと ', () => { ... }); ✅ Good ❌
Bad it('onSubmit が navigate('/confirm') を呼ぶこと', () => { ... }); ユーザーの行動と成果が主語になるように書く
ユーザー体験にどうつながるのか🤔を見極めやすくなる ビジネス的な効果の薄いテストを疑うトリガーになる
テストファイルはコロケーションする
テストファイルは__tests__/とかtests/ に置くのではなく テスト対象のコードの同じディレクトリ配下に置く route/ └── top/ ├── route.tsx └── top.test.tsx
⬅ util/ └── date/ ├── date.test └── date.test.tsx ⬅ tests/ ├── route/ │ ├── top.test.tsx │ └── job-detail.test.tsx └── test/ ├── top.test.tsx └── job-detail.test.tsx ✅ Good ❌ Bad
テストをアプリケーションコードとコロケーションすることで、 • 「隣のテストも直す」意識が働き、 テストのメンテが置き去りになりにくい • 関連ファイルが近接していると、AIが文脈を取り込みやすい 人もAIもテストを見失わないようにするために テストはコロケーションする
さいごに
さいごに • FEがBEを通信する層を厚くテストする • UIは共通コンポーネントに絞ってテストする • 人もAIも迷わないように、書き方・名前・配置を工夫する AIコーディングで開発スピードを上げつつ、テストで品質を支える