---
title: 【ファインディ株式会社】そのテスト、バグっても気づけません【Human in the loop? Human on the loop? meetup】
tags: 
author: [もっくま](https://docswell.com/user/mot0aki)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/GE8D368RED.jpg?width=480
description: ファインディ株式会社 Human in the loop? Human on the loop? meetup  のLT資料です。  https://findy-aiplus.connpass.com/event/401925/
published: August 31, 26
canonical: https://docswell.com/s/mot0aki/5VJ2JQ-mutationAI
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/GE8D368RED.jpg)

#HUMANONTHELOOP ・ 2026. 08. 31
そのテスト、
バグっても気づけません
〜 AIが書いたテスト、本当に意味のあるテストになっていますか 〜
Motoaki Tanaka @mot0aki


# Page. 2

![Page Image](https://bcdn.docswell.com/page/LELMV9R27R.jpg)

自己紹介
Motoaki Tanaka X: @mot0aki
▸ 株式会社レッドジャーニー
ソフトウェアエンジニア
アジャイル開発推進
新規プロダクト開発・プロダクトマネジメント
生成AI開発・導入支援
AIカタリスト
@mot0aki ・ Human in the loop? Human on the loop? meetup
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/4JMYGZR9JW.jpg)

AI駆動開発ではハーネスが大事
AIも人も、どんどんコードを書く
▼ 壊れたまま進まないよう、ハーネスで受け止める
型・Lint
書いた時点で弾く
自動テスト
壊れたら気づく
CI/CD
出す前に止める
ハーネス
人が全部見るのをやめられるのは、このハーネスが効いているからです。
@mot0aki ・ Human in the loop? Human on the loop? meetup
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/PJR9Z6R979.jpg)

自動テスト
実装した機能が想定通り動くことを、簡単に担保できる
そして最近は、テストコードもAIに書いてもらうようになってきました。
@mot0aki ・ Human in the loop? Human on the loop? meetup
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/PEXQ9MR3JX.jpg)

では、あなたのプロダクトは
十分にテストできていますか？
@mot0aki ・ Human in the loop? Human on the loop? meetup
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/3EK9PGRNED.jpg)

1つの目安 → カバレッジ
実装コードのうち、どのくらいテストできているかを示す指標
@mot0aki ・ Human in the loop? Human on the loop? meetup
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/L73WXN8Z75.jpg)

カバレッジが見せているのは「実行されたか」だけ
カバレッジが見ているもの
実装コード → テストを実行 → 通った ＝ この行は実行された
カバレッジでは見えないもの
実装コードを壊す → テストを実行 → やっぱり通った ＝ 壊れても気づけない
そのテストコードが、バグを埋め込んだときに気づけるテストになっているかは分かりません。
@mot0aki ・ Human in the loop? Human on the loop? meetup
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/87DK2WM4JG.jpg)

AIが書いてくれたそのテストコード、
本当に意味のあるテストになっています
か？
@mot0aki ・ Human in the loop? Human on the loop? meetup
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/VJPK19RVE8.jpg)

実装を壊してもテストは通ってしまう
実装 / isAdult.ts
&gt;=
の = を1文字消してみる
return age &gt;= 18;
// isAdult(18) → true
return age &gt;
// isAdult(18) → false
18;
テスト / isAdult.test.ts
境界から離れた値しか見ていないテスト
(カバレッジは100%)
expect(isAdult(25)).toBe(true);
もし 18歳の扱いは変わる。でも18歳以外の結果は1つも
変わらない。
expect(isAdult(16)).toBe(false);
結果 25も16も &gt;= と &gt; で答えが同じなので1本も落ち
ない。
テストはある。実行もされている。それでも壊れたことに気づかない。
@mot0aki ・ Human in the loop? Human on the loop? meetup
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/2EVVYMRREQ.jpg)

02
そこで導入してみたのが
MutationTest
ミューテーションテスト ── テストが「気づけるか」を機械的に確かめる
@mot0aki ・ Human in the loop? Human on the loop? meetup
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/57GL9GM6EL.jpg)

MutationTest ＝ わざと壊してテストを走らせる
▶
実装コード
1か所だけ
機械的に書き換える
Mutant
▶
既存のテストを
そのまま走らせる
▶
落ちた → Killed
通った → Survived
例)
if (price &gt; 1000)
→
if (price &gt;= 1000)
// 境界をずらす
if (isAdmin)
→
if (true)
// 条件を常に成立させる
msg = &quot;saved&quot;
→
msg = &quot;&quot;
// 文字列を空にする
この書き換え1つが Mutant。1ファイルでも数十〜数百個が自動でつくられます。
@mot0aki ・ Human in the loop? Human on the loop? meetup
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/4EQYWXR2JP.jpg)

落ちれば Killed、通ってしまえば Survived
Killed
テストが落ちた
壊したことに気づけた。テストが効いている証拠。
Survived
テストが通ってしまった
壊しても誰も気づかない。ここが実質の穴。
Mutation Score ＝ Killed ÷ Mutant数
テストが気づけた割合
カバレッジは実行されたか、Mutation Score は壊れたときに気づけるかを見ます。
変異ごとにテストを回すため実行時間は長い。まずは1ファイルに絞るのが現実的です。
@mot0aki ・ Human in the loop? Human on the loop? meetup
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/KJ4WK68P71.jpg)

国内にも実践例がある
01
AIが書いたテストを
検証する
LLMが生成したテストの品質を
Mutation Testing で確かめる
KAKEHASHI Tech Blog・2026
02
フロントエンドに
導入する
JS向けライブラリ Stryker を実戦
導入した記録
Zenn・hitocolor
@mot0aki ・ Human in the loop? Human on the loop? meetup
03
テストの十分性を
評価する
ミューテーションテストの技法とし
て整理されている
豆蔵デベロッパーサイト・2024
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/LE1YXV2X7G.jpg)

03
フロントエンドでも
導入しています
@mot0aki ・ Human in the loop? Human on the loop? meetup
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/GEWGNLRKJ2.jpg)

フロントエンドではこのように検知されます
@mot0aki ・ Human in the loop? Human on the loop? meetup
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/47ZL3MRNJ3.jpg)

なぜ生き残ったのか
テストが見ていた範囲
ワークスペース一覧
AAA111 質問 3 件
リンクはある・名前も AAA111・件数も合う
───────▶
to={`/${ws.code}`}
この矢印だけ
誰も見ていなかった
ワークスペース詳細
/AAA111
を空にしてもリンクは消えず、一覧ページ自身を指すだけ。role も表示名も変わらないので、テストは通ってし
まいます。
to
@mot0aki ・ Human in the loop? Human on the loop? meetup
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/YJ6WXNR9JV.jpg)

テストを修正（足りないケースを追加）
// フロントエンドのテストコードの例
it(&#039;一覧のリンクをクリックするとそのワークスペースのページへ遷移する&#039;, async () =&gt; {
renderWithProviders(
&lt;Routes&gt;
&lt;Route path=&quot;/workspaces&quot; element={&lt;MyWorkspacesPage /&gt;} /&gt;
&lt;Route path=&quot;/:code&quot; element={&lt;WorkspacePage /&gt;} /&gt;
&lt;/Routes&gt;,
{ initialEntry: &#039;/workspaces&#039; },
);
// AAA111 をクリックしたら
await user.click(await screen.findByRole(&#039;link&#039;, { name: /AAA111/ }));
// AAA111 のページが表示されていることを確認
expect(await screen.findByTestId(&#039;ws-code&#039;)).toHaveTextContent(&#039;AAA111&#039;);
});
@mot0aki ・ Human in the loop? Human on the loop? meetup
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/GJ5MX58DJ4.jpg)

修正されたことが確認できた
76行目の Survived が消え、 Killed になりました！
@mot0aki ・ Human in the loop? Human on the loop? meetup
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/LE3WXNGQE5.jpg)

プロダクトでは2段構えで回しています
① 実装中 ── Hooks で自動実行（対象は変更差分のみ）
エージェントが実装 → 差分に MutationTest → Survived → サブエージェントが検証・修正
② PR作成時 ── CI でチェック
PR を作成 → CI でも MutationTest → 見逃しを人間が検知
まずエージェントのループ内で自動修正し、すり抜けた分は PR の CI で人間が気づけるようにしています。
@mot0aki ・ Human in the loop? Human on the loop? meetup
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/8EDK2W1W7G.jpg)

実行スコープとリードタイムのトレードオフ
MutationTest は変異の数だけテストを回すので、実行時間はどうし
ても長い
スコープ広め
スコープ狭め
そのぶん実行時間が伸びて、エージェントのループが止
まる
そのぶん見える範囲は狭くなる
見つけられる穴は増える
結果がすぐ返ってくる
実行スコープは「その場面でどれだけ待てるか」から決める
速さが要る場面ほど、スコープを絞る
@mot0aki ・ Human in the loop? Human on the loop? meetup
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/V7PK19QXJ8.jpg)

MutationTestで
空虚なテストを減らしていこう！
@mot0aki ・ Human in the loop? Human on the loop? meetup
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/2JVVYM53JQ.jpg)

ご清聴ありがとうございました。 @mot0aki
@mot0aki ・ Human in the loop? Human on the loop? meetup


