なぜ、AIに任せた4つの技術検証は、毎回違う『実機でしか出ないバグ』を連れてきたのか?

AI活用術

課題

AIに実装を任せていると、「flutter analyzeも単体テストも全部通りました」という報告を受けて、つい「これで大丈夫」と思ってしまう。でも、それだけでは気づけない不具合がある。

この記事でわかること

  • 単体テストの守備範囲と、実機・エミュレータで動かして初めて気づける不具合の違い
  • 似た技術検証を4回連続でAIに実装してもらった際に、毎回違う顔をして現れた「実機でしか出ない不具合」の実例4件

解決できたこと

自動テストが通っていることと、実際に画面を動かして問題が無いことは別物だと、4つの実例を通じて具体的に確認できる。何を確認すれば同じ落とし穴を避けられるかもまとめた。

この記事を読んで、こう思うかもしれない。

「AIが『テストは全部通りました』って報告してきたら、もう安心していいんじゃないの?」

実は違う。今回の4つの技術検証は、どれもテストが通った後の実機確認で初めて不具合が見つかった。

本文

似た技術検証を、4つ連続でAIに実装してもらった

自分は個人開発のモバイルアプリPortfolioの一環として、「学習Track」という技術検証専用の小さなアプリ群を作っている。将来作りたい本命の企画(都市育成×攻め込みゲーム)に必要な技術要素を、先に小さく試しておくための試作という位置づけで、実装自体はAIに任せている。

今回はそのうち4つを、数日おきに連続でAIに実装してもらった。A*経路探索を試すmini_walker(ミニウォーカー、タップした場所まで自動で道を探して歩くゲーム)、Boidsアルゴリズムで群れの動きを再現するflock_march(フロックマーチ、複数キャラが群れになって移動するゲーム)、タワー防衛の戦闘ロジックを検証するtower_siege(タワーシージ)、そして最後にそれらを組み合わせたbase_raid(ベースレイド)。

どのStepでも、AIは実装後にflutter analyzeと単体テストを走らせて「問題なし」を確認してから、Androidエミュレータで実際に動かして最終確認する、という同じ手順を踏んでいた。ところが、この最後の「実際に動かす」ステップで、4回とも何かしらの不具合をAIが見つけてきた。しかも毎回、原因の種類が違う。

1つ目: グリッドが画面の上に偏っていた(mini_walker)

最初のmini_walkerでは、AIがAndroidエミュレータで画面を開いたところ、カメラの基準点(viewfinder anchor)が画面の左上(topLeft)になっていたせいで、縦長の画面だとグリッド全体が上のほうに偏って表示されることが分かったと報告があった。

基準点を画面中央(center)に変えるだけで直る話だったので、深刻な不具合ではない。ただ、コードを読んでいるだけでは気づけない類の話で、実際に画面を開いて初めて「見た目がおかしい」と分かるものだった。AIは直した後、グリッド表示・目的地タップでの経路探索・壁の設置・迂回経路での到達、という4項目をスクリーンショットで確認して完了とした。

2つ目と3つ目: 群れが1点に潰れる、壁を抜けた瞬間に止まる(flock_march)

次のflock_marchでは、Boids(群れの動きをシミュレーションするアルゴリズム)をAIが実装した。ここでAIが実機確認中に不具合を2つ見つけてきた。

1つ目は、50体のキャラが視覚的に完全に1点へ収束してしまい、画面上では1体にしか見えなくなる不具合。原因は、全個体が同じ座標を目指して移動していたこと。各個体に「群れの中でのポジション」を表す固定オフセットを持たせることで解消した。

2つ目は、壁の切れ目(隘路)を通り抜けた直後、群れ全体がピタッと止まってしまう不具合。こちらの原因はもう少し込み入っていて、個体同士の反発力(separation)を「距離の逆数」で計算していたせいで、隘路のように個体同士の距離が0に近づく場面で計算結果が発散し、目的地へ向かう本来の力を完全に押しつぶしてしまっていた。反発力の計算式を「距離に比例した有界な式」に直し、目的地へ向かう力を強め、膠着を検知したら強制的に次の目印へ進ませる安全策も追加して、ようやく収まったとの報告だった。

AIからの報告を見ると、単体テストは6件通っている段階のはずなのに、実際に動かすと群れが固まる、という話になっていた。「あれ、テスト通ってるのになんでだ」と最初は思ったけれど、よく考えれば無理もない。単体テストが確認していたのはBoids1体分の力の計算が正しいかどうかで、50体が密集する隘路という「複数の個体が同時に絡み合う場面」までは、そもそもテストの対象になっていなかった。

4つ目: 敵が的の届かない場所で立ち止まる(tower_siege)

3つ目のtower_siegeでは、タワー防衛の戦闘シミュレーションをAIが実装した。実機で動かしたところ、敵キャラが向かう先に固定していたマスが、たまたまどちらのタワーの射程(100px)にも入らないほど離れた位置だったため、敵がそこに到着した後、タワーと敵の双方が「相手が射程外だから」何もできずに固まってしまう不具合をAIが見つけた。

敵の移動先を「固定のマス」から「今いちばん近い、生き残っているタワーのマス」へ動的に変えるよう直し、あわせて敵の射程そのものも26pxから60pxへ広げた。修正後は、防衛失敗という結果まできちんとシミュレーションが決着することを確認できたという。単体テスト7件はダメージ計算や射程判定そのものは検証していたけれど、マップ上のどこにタワーと敵が配置されるか、という組み合わせの問題までは検証範囲の外だった。

5つ目: タイマーが動いた瞬間だけ赤い画面が出る(base_raid)

最後のbase_raidは、それまでの3つを統合する実装をAIに任せた。ここでAIが見つけた不具合は、これまでの3つとは毛色が違った。

AIが正式なアイコンを適用した後、実機で「始める」をタップして確認したところ、setState() or markNeedsBuild() called during build.という赤いエラー画面が出た。原因を辿ると、base_raidで新しく作った「毎フレーム呼ばれるタイマーのコールバック」が、画面が最初に描画されるタイミングとぶつかってsetState()を呼んでしまっていたことが分かった。前身のtower_siegeにあった似たコールバックは「決着した瞬間の1回だけ」しか呼ばれない作りだったので、この競合はそもそも起きようがなかった。base_raidで初めて「毎フレーム呼ぶ」仕組みを追加したことで、新たに表面化した問題だった。

修正自体は、該当のコールバックをWidgetsBinding.instance.addPostFrameCallbackで包んで、画面の描画が終わってから呼ばれるようにするというもの。直した後、AIはタイマーHUDのカウントダウンや戦闘アニメーション、勝敗バナーまで、全部正常に動くことを確認した。ここでのポイントは、直前に走らせていたテストが「ホーム画面から拠点攻略画面への遷移と、1回タップする」という短いシナリオしか確認していなかったこと。タイマーが実際に時間を刻み続ける状況までは、そもそもテストが再現していなかった。

4回とも「テストは通ってる、でも動かすと違う」

AIから3回目、4回目と続けて「実機で確認したら不具合がありました」という報告が来たあたりで、さすがに「これ、毎回同じパターンじゃないか」と思うようになった。実際に4つの技術検証を振り返ると、見た目のバグの種類はバラバラなのに、共通するパターンが1つ浮かび上がる。どのケースも、flutter analyzeと単体テストは実装直後の時点で問題なしを示していて、実際にエミュレータで画面を動かして、複数の要素が同時に絡み合う場面(密集・配置の組み合わせ・時間経過)まで再現して、初めて不具合が姿を現した。

単体テストが悪いわけではない。ただ単体テストは「1つの部品が単独で正しく動くか」を確認するもので、「複数の部品が実際の場面で組み合わさったときにどうなるか」までは、意識して作らない限りカバーしてくれない。今回の4件でいえば、密集した個体同士の力の相互作用(flock_march)、マップ上の座標の組み合わせ(tower_siege)、フレームのタイミング(base_raid)は、どれも「実際に動かしてみないと現れない」種類の問題だった。

まとめ

似た技術検証をAIに4回連続で実装してもらっても、毎回違う顔をした「実機でしか気づけない不具合」が出てきた。単体テストと解析が通っているという報告と、実際に動かして問題が無いことは、やっぱり別物だと実感した。

項目内容
結論単体テストが通っていても、複数要素が絡み合う場面(密集・配置・時間経過)は実機確認でしか気づけない
教訓前身の実装との差分(今回なら「毎フレーム呼ばれる処理を新たに追加した」点)に注目すると、新しく起きうる不具合の見当がつけやすい
対象読者AIに実装を任せていて、「テストが通りました」という報告だけで安心しがちな人

同じ状況に陥ったときの回避策

  • AIから「テストは全部通りました」と報告が来ても、それだけで「完成」とせず、実機・エミュレータで実際に動かす工程を必ず挟んでもらう
  • 特に、複数のキャラや要素が同時に動く場面(密集、配置の組み合わせ、時間経過)は、単体テストの対象になっていないことが多いので、意識して確認を依頼する
  • 前身の似た実装との差分(今回でいえば「毎フレーム呼ばれる処理を新たに追加した」点)に注目すると、新しく発生し得る不具合のあたりがつけやすい

この記事は、筆者が実際に個人開発しているアプリ(技術検証用の学習アプリ群)の開発記録(2026年8月29日〜31日)を基に、独自調整したAIが下書きを作成し、筆者が事実確認・編集を行った上で公開しています。

PAGE TOP
タイトルとURLをコピーしました