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
ディップ株式会社
PRO
October 06, 2025
Technology
55
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 ディップ株式会社
はじめての環境構築!デプロイ〜Docker基礎を学べるワークショップ!
dip_tech
PRO
0
36
【TSKaigi2026登壇資料】決定論的な型チェックへ Go 製コンパイラによる10倍速の裏側で stableTypeOrdering から見える並列化への挑戦
dip_tech
PRO
2
380
【TSKaigi2026登壇資料】バイトル」のTypeScriptリニューアル — 積み上がったレガシーとパフォーマンスに挑む現在地
dip_tech
PRO
1
350
【新卒研修】ライブデモ + compose.yaml読解_講義資料
dip_tech
PRO
0
240
【ディップ|26年新卒研修資料】OpenAPI/Swagger REST API研修
dip_tech
PRO
0
380
【ディップ|26年新卒研修資料】Docker_ハンズオン研修
dip_tech
PRO
0
350
【ディップ|26年新卒研修資料】TDD実装演習
dip_tech
PRO
0
400
ハッカソンや個人開発で何作る? テーマ発見〜アイデア発想ハンズオン! 技育CAMPアカデミア
dip_tech
PRO
0
87
技育祭登壇|「AIを使える」は、勘違いだった。 コードが書けてもプロになれなかった僕の1年戦記
dip_tech
PRO
0
140
Other Decks in Technology
See All in Technology
AI Testing Talks: Challenges of Applying AI in Software Testing: From Hype to Practical Use
exactpro
PRO
1
140
Ruby::Boxでできること、Refinementsでできること
joker1007
3
400
美味しいスイスチーズを作ろう🧀🐭
taigamikami
1
270
データ基盤をDataformで整えた話 〜 開発環境を添えて 〜
takapy
0
130
Socrates × Looker 〜セマンティックレイヤーで進化するデータ分析エージェント〜
hanon52_
2
1.5k
Chart.js が簡単に使えるようになっていたので OGP 画像生成に使った話
kamekyame
0
170
Databricks における 生成AIガバナンスの実践
taka_aki
1
360
AIソロプレナー時代に2ヶ月で20人増員した事業創造会社の開発組織の話
miyatakoji
0
260
MIERUNE JCT 発表資料「宇宙から伊能忠敬ごっこ」
syuchimu
0
190
マーケットプレイス版Oracle WebCenter Content For OCI
oracle4engineer
PRO
5
1.8k
サイバーセキュリティ概論 / Introduction to Cybersecurity
ks91
PRO
0
170
AIを「創る」と「使う」の循環 — HRテックが実践するリアルなAI組織実装
taketo957
0
1.8k
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
9
860
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
220
The Cost Of JavaScript in 2023
addyosmani
55
10k
Test your architecture with Archunit
thirion
1
2.3k
Site-Speed That Sticks
csswizardry
13
1.2k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
200
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
140
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
160
Documentation Writing (for coders)
carmenintech
77
5.4k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
840
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コーディングで開発スピードを上げつつ、テストで品質を支える