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が出力するテストコードのリアル よくあるコードと改善のヒント
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
starfish719
November 18, 2025
Technology
870
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
生成AIが出力するテストコードのリアル よくあるコードと改善のヒント
starfish719
November 18, 2025
More Decks by starfish719
See All by starfish719
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
3.3k
「速く作る」から「正しく作る」へ ─ 生成AI時代の開発フロー改革の ロードマップと実行 ─
starfish719
1
12k
AI活用を推進するために ファインディが下した、一つの小さな決断
starfish719
0
380
生成AI時代のエンジニア育成 変わる時代と変わらないコト
starfish719
0
15k
【Claude Code】Plugins作成から始まったファインディの開発フロー改革
starfish719
0
1.1k
Findy AI+の開発、運用におけるMCP活用事例
starfish719
0
4k
生成AI時代に若手エンジニアが最初に覚えるべき内容と、その学習法
starfish719
2
930
開発生産性を上げるための生成AI活用術
starfish719
3
3.3k
ファインディ株式会社におけるMCP活用とサービス開発
starfish719
0
5k
Other Decks in Technology
See All in Technology
脱Jenkins、インターン生が挑んだCIツールGitHubActions移行
mixi_engineers
PRO
1
300
Power Automateアップデート情報
miyakemito
0
290
ガバメントクラウドでのランサムウェア対策
techniczna
1
520
ここは地獄!つらい朝会を体験することで、チームとしてのより良い振る舞いに気づくワークショップ / The stand-up meeting from hell in the game industry
scrummasudar
0
520
Pavlokで始める電撃駆動開発
sgrsn
0
140
オートロックマンションなのに、各部屋は施錠なし!? 攻撃者が組織内ネットワークで大暴れする理由 / The Front Door Is Locked, but the Rooms Are Wide Open: Why Attackers Move Freely Inside Enterprise Networks
nttcom
0
730
WEBフロントエンド研修【MIXI 26新卒技術研修】
mixi_engineers
PRO
2
900
もう一度考える SRE チームの作り方・育て方 / Rethinking SRE #1: Building and Growing SRE Teams
rrreeeyyy
4
640
A Bag-of-Documents Model for Query Specificity
dtunkelang
0
190
信頼できるテスティングAIをどう育てるか?
odan611
0
180
数値で見る Microsoft MVP 〜Spec Kit と GitHub Copilot Agent で作るデータ可視化ダッシュボード〜
yutakaosada
0
180
セキュリティ研修【MIXI 26新卒技術研修】
mixi_engineers
PRO
32
27k
Featured
See All Featured
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
3
380
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.7k
Designing for Performance
lara
611
70k
Scaling GitHub
holman
464
140k
Evolving SEO for Evolving Search Engines
ryanjones
0
250
Test your architecture with Archunit
thirion
1
2.3k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
620
Marketing to machines
jonoalderson
1
5.6k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
The Cult of Friendly URLs
andyhume
79
7k
Transcript
© Findy Inc. 2025.11 Findy AI Meetup ⽣成AIが出⼒するテストコードのリアル よくあるコードと改善のヒント 1
ファインディ株式会社 テックリードマネージャー ⼾⽥ 千隼 @starfish0206
© Findy Inc. 2 ⽣成AI時代のテストコードの役割
© Findy Inc. 3 暴⾛を防ぐためのガードレール • テストコードが持つ役割 ◦ 仕様を把握するための情報源 ◦
暴⾛しないためのガードレール • ⽣成AIが出⼒したコードが原因で既存のテストコードが失敗した場合 ◦ エラー内容を元に⽣成AIが実装または、テストコードを修正する ◦ エラーの原因がどこにあるのかの判断を間違えないことがポイント • 「何が正しいのか」を⽣成AIが理解することで、出⼒内容の⽅向性がズレないようにする
© Findy Inc. 4 ⽣成されるテストコードの実状と改善⽅法
© Findy Inc. 不要な新規ケースが追加される 5
© Findy Inc. 6 どんどんテストケースが追加されてしまう • 既存のテストケースに⼿を加えればいいだけなのに、新しいテストケースが追加されてし まう ◦ モデルなどに項⽬追加する時に⾒られる
• テストケースの名称がポイントになる
© Findy Inc. 7 class TestUserModel: def test_user_attributes(self): user =
User( name="Test User", is_deleted=True ) assert user.name == "Test User" assert user.is_deleted is True def test_user_default_is_deleted(self): user = User( name="Test User", ) assert user.is_deleted is False
© Findy Inc. 8 class TestUserModel: def test_user_attributes(self): user =
User( name="Test User", role="admin", is_deleted=True ) assert user.name == "Test User" assert user.role == "admin" assert user.is_deleted is True def test_user_default_is_deleted(self): user = User( name="Test User", ) assert user.is_deleted is False def test_user_default_role(self): user = User( name="Test User", ) assert user.role == "member"
© Findy Inc. 9 class TestUserModel: def test_user_attributes(self): user =
User( name="Test User", role="admin", is_deleted=True ) assert user.name == "Test User" assert user.role == "admin" assert user.is_deleted is True def test_user_default_is_deleted(self): user = User( name="Test User", ) assert user.is_deleted is False def test_user_default_role(self): user = User( name="Test User", ) assert user.role == "member"
© Findy Inc. 10 class TestUserModel: def test_user_attributes(self): user =
User( name="Test User", role="admin", is_deleted=True ) assert user.name == "Test User" assert user.role == "admin" assert user.is_deleted is True def test_user_default_attributes(self): user = User( name="Test User", ) assert user.role == "member" assert user.is_deleted is False
© Findy Inc. 11 class TestUserModel: def test_user_attributes(self): user =
User( name="Test User", role="admin", is_deleted=True ) assert user.name == "Test User" assert user.role == "admin" assert user.is_deleted is True def test_user_default_attributes(self): user = User( name="Test User", ) assert user.role == "member" assert user.is_deleted is False まずは既存のテストコードを⾒直す
© Findy Inc. テストを通すためのテスト 12
© Findy Inc. 13 無理やりテストを通そうとする • テストを通すための修正をやりがち ◦ テストが通るまでトライアンドエラーを繰り返す ◦
⾊々試している流れでテストが通ったら、それが正解だと判断されてしまう • 適切にmockを使いましょう
© Findy Inc. 14 class TestEmailService: def test_create_invite_mail_body(self): to_email =
"
[email protected]
" invite_link = "https://example.com/invite/12345" text_body = email_service.create_invite_mail_body(to_email, invite_link) assert f"{to_email}様" in text_body assert invite_link in text_body assert "このリンクの有効期限は " in text_body assert "です" in text_body
© Findy Inc. 15 class TestEmailService: def test_create_invite_mail_body(self): to_email =
"
[email protected]
" invite_link = "https://example.com/invite/12345" text_body = email_service.create_invite_mail_body(to_email, invite_link) assert f"{to_email}様" in text_body assert invite_link in text_body assert "このリンクの有効期限は " in text_body assert "です" in text_body - 有効期限の⽇時の確認が漏れている - 意図しない⽂字列が⼊っていても通っ てしまう
© Findy Inc. 16 class TestEmailService: def test_create_invite_mail_body(self, monkeypatch): mock_datetime
= MagicMock() mock_datetime.now.return_value = datetime(2025, 11, 1, 0, 0, 0, tzinfo=UTC) monkeypatch.setattr("src.service.email.datetime", mock_datetime) to_email = "
[email protected]
" invite_link = "https://example.com/invite/12345" text_body = email_service.create_invite_mail_body(to_email, invite_link) assert text_body == f"{to_email}様\n{invite_link}\nこのリンクの有効期限は 2025/11/15 です。"
© Findy Inc. 17 class TestEmailService: def test_create_invite_mail_body(self, monkeypatch): mock_datetime
= MagicMock() mock_datetime.now.return_value = datetime(2025, 11, 1, 0, 0, 0, tzinfo=UTC) monkeypatch.setattr("src.service.email.datetime", mock_datetime) to_email = "
[email protected]
" invite_link = "https://example.com/invite/12345" text_body = email_service.create_invite_mail_body(to_email, invite_link) assert text_body == f"{to_email}様\n{invite_link}\nこのリンクの有効期限は 2025/11/15 です。" ケースに応じたmockの使⽤⽅法を カスタムインストラクションなどに 追記
© Findy Inc. システムを守るテスト 18
© Findy Inc. 19 現状は問題ないが、拡張してもコケてくれない • テストを通すことが⽬的ではない ◦ 適切な理由とタイミングでコケるのが良いテスト •
意図しない変更を、テストがコケることで事前に検知したい ◦ 何がどうなったらテストがコケてくれるのかをイメージしましょう
© Findy Inc. 20 class TestGetUserById: def test_get_user_by_id_success(self, client): target_user
= User( name="Test User", ) response = client.get(f"/api/v1/users/{target_user.id}") assert response.status_code == status.HTTP_200_OK assert response["id"] == target_user.id assert response["name"] == "Test User"
© Findy Inc. 21 class TestGetUserById: def test_get_user_by_id_success(self, client): target_user
= User( name="Test User", ) response = client.get(f"/api/v1/users/{target_user.id}") assert response.status_code == status.HTTP_200_OK assert response["id"] == target_user.id assert response["name"] == "Test User" responseに項⽬が 追加されてもコケない
© Findy Inc. 22 class TestGetUserById: def test_get_user_by_id_success(self, client): target_user
= User( name="Test User", ) response = client.get(f"/api/v1/users/{target_user.id}") assert response.status_code == status.HTTP_200_OK assert response.json() == { "id": target_user.id, "name": "Test User", }
© Findy Inc. class TestGetUserById: def test_get_user_by_id_success(self, client): target_user =
User( name="Test User", ) response = client.get(f"/api/v1/users/{target_user.id}") assert response.status_code == status.HTTP_200_OK assert response.json() == { "id": target_user.id, "name": "Test User", } 23 意図しない項⽬追加時に コケてくれる ケースごとの テストのサンプルコードを カスタムインストラクションに追記
© Findy Inc. 24 まとめ
© Findy Inc. まとめ 25 • ⽣成AIが出⼒するテストコードの質には伸び代がある ◦ 伸び代ポイントを⾒つけた場合 ▪
既存のテストコードの⾒直し ▪ カスタムインストラクションなどにサンプルコードを記述 • ⽣成AI時代のテストコードが持つ役割は、今までよりも重要になった ◦ 出⼒される実装コードの質を向上させるために、テストコードとも向き合いましょう ファインディに興味がある⽅は、ぜひカジュアル⾯談しましょう
© Findy Inc. ご清聴ありがとうございました 26