- Metaが2月に発表した論文 "Automated Unit Test Improvement using Large Language Models at Meta" で、TestGen-LLMというツールが紹介された
- このツールの目的は、完全に自動化された方式でテストカバレッジを高め、既存のコードベースより改善されることを保証すること
- MetaはTestGen-LLMのコードを公開していないため、オープンソースのCover Agentの一部として自ら実装することにした
- ここでは、実装過程、判明したこと、実際のコードベースでTestGen-LLMを使う際に直面した問題点などを共有する
自動テスト生成の基準
- 生成AIを使った自動テスト生成は新しいものではない
- ほとんどのLLMはコード生成に長けており、テスト生成も可能
- 開発者がLLMでテストを生成するときにぶつかる最も一般的な問題は、生成されたテストの大半が動作しないか、価値を付加しないこと
- これを克服するため、TestGen-LLMの著者らは回帰単体テストについて次のような基準を提示している:
- テストは正しくコンパイルされ、実行されるか?
- テストはコードカバレッジを高めるか?
- この2つの基本的な問いに答えられなければ、LLMが提供した生成テストを受け入れたり分析したりする理由はない
- この問いを通過したら、その次に手動レビューを行う
- テストはどれだけ適切に書かれているか?
- 実際にどれだけの価値を追加できるか?
- 追加要件を満たしているか?
TestGen-LLMのアプローチと報告された結果
- TestGen-LLM(およびCover-Agent)は完全にヘッドレスで実行される
- まず大量のテストを生成し、その後ビルド/実行できないものをフィルタリングし、通らないものを捨て、コードカバレッジを高めないものは破棄する
- 非常に統制されたケースでは、生成されたテストに対してすべての段階を通過する比率は1:4で、実際のシナリオではMetaの著者らは1:20の比率を報告している
- 自動化プロセスの後、Metaは人間のレビュアーがテストを受け入れるか拒否するかを判断するようにしている
- 論文の著者らは、最良の場合で73%の受け入れ率、平均で1:2の採用比率を示したとしている
- 論文で説明されている通り、TestGen-LLMツールは各実行ごとに、専門の開発者が以前に作成した既存のテストスイートに追加される単一のテストを生成する
- また、与えられたテストスイートに対して必ずしもテストを生成するわけではない
Cover-Agentの実装
- Cover-Agent v0.1は次のように実装されている:
- ユーザー入力を受け取る(テスト対象のソースファイル、改善する既存テストスイート、カバレッジレポート、テストスイートのビルドおよび実行コマンド、コードカバレッジ目標と最大反復実行回数、追加コンテキストとプロンプトオプション)
- 同じスタイルでさらに多くのテストを生成
- ランタイム環境を使ってそのテストを検証(ビルドできるか、通過するか)
- コードカバレッジ増加のようなメトリクスを確認し、テストが価値を付加するかを判断
- 既存のテストスイートとカバレッジレポートを更新
- コードが基準に到達するまで反復(コードカバレッジ閾値に到達、または最大反復回数に到達)
TestGen-LLMの実装と検証で直面した問題点
- 論文で提示された例では、空白が重要ではないKotlinをテスト記述に使っている
- 一方、Pythonのような言語では、タブや空白が重要であるだけでなく、パーシングエンジンにとって必須
- GPT 3.5のような比較的洗練度の低いモデルは、明示的にプロンプトを与えても、一貫して適切にインデントされたコードを返さない
- これが問題になる例として、各テスト関数がインデントされなければならないPython製のテストクラスがある
- そのため、これを開発ライフサイクル全体で考慮する必要があり、前処理ライブラリ周辺にさらに複雑さが加わった
- このようなシナリオでCover-Agentを堅牢にするには、まだ改善すべき点が多い
- Cover-Agentのフローの一部として、ユーザーがLLMに追加の入力や指示を与えられる機能を追加した(
--additional-instructions オプション)
- これにより開発者は、プロジェクト固有の追加情報を提供してCover-Agentをカスタマイズできる
- たとえばこの指示を使って、意味のあるエッジケースを備えた充実したテストセットを作るようCover-Agentを誘導できる
- AIベースのアプリケーションでRetrieval-Augmented Generation(RAG)がより広く普及している一般的な流れと同様に、単体テスト生成でもより多くのコンテキストを持つことで、より高品質なテストとより高い通過率が可能になることを確認した
- テスト生成プロセスを改善するため、LLMへのコンテキストとして追加ライブラリやテキストベースの設計文書を手動で追加したいユーザー向けに
--included-files オプションを提供している
- 複数回の反復が必要な複雑なコードは、LLMにとって別の課題を提示する
- 失敗した(または価値を付加しなかった)テストが生成されるにつれ、後続の反復で同じ不採用テストが繰り返し提案されるパターンが見え始めた
- これを解決するため、プロンプトに "失敗したテスト" セクションを追加してそのフィードバックをLLMに渡し、ユニークなテストを生成し、使えないと判断した(つまり壊れている、またはカバレッジ増加が不十分な)テストを決して繰り返さないようにした
- 既存のテストスイートを拡張する際にライブラリのインポートを追加できない点も、この過程全体で提起された別の問題
- 開発者はテスト生成プロセスにおいて、時にテストフレームワークへの単一のアプローチしか使わない近視眼的な見方に陥りがち
- 多様なモックフレームワークに加え、他のライブラリもテストカバレッジ達成に役立つ可能性がある
- TestGen-LLM論文(およびCover-Agent)は既存のテストスイートを拡張することを目的としているため、テストクラス全体を完全に再構成することは範囲外
- これはテスト生成に対比されるテスト拡張の限界であり、今後の反復で解決する予定
- TestGen-LLMのアプローチでは、各テストについて次のテストが提案される前に開発者の手動レビューが必要である点を区別しておくことが重要
- 一方Cover-Agentでは、カバレッジ要件を達成するか(または最大反復で停止する)まで、プロセス全体を通して手動介入なしに、可能な限り多くのテストを生成・検証・提案する
- AIを活用してバックグラウンドで実行し、開発者がプロセス完了後にテストスイート全体を一度にレビューできる、邪魔されない自動テスト生成アプローチを作り出している
結論と今後の計画
- 多くの人(自分自身を含む)がTestGen-LLM論文とツールに期待しているが、この投稿ではその限界について語っている
- 私たちは依然として、完全自動化ワークフローを実行するAIチームメイトの時代ではなく、AIアシスタントの時代にいると考えている
- 同時に、よく設計されたフローは、開発者がテスト候補を自動生成し、はるかに短時間でコードカバレッジを高める助けとなり得て、これはCover-Agentで開発し共有していく予定
- テスト生成分野に関連する最先端手法を継続的に開発し、Cover-Agentのオープンソースリポジトリに統合していく予定
- テスト向け生成AIに関心のあるすべての人が協業し、Cover Agentの機能拡張に協力してくれることを望むとともに、このオープンソースツールを活用して新しいテスト生成技術を探求するよう研究者を刺激したい
- GitHubのオープンソースCover-Agentリポジトリに開発ロードマップを追加しており、そのロードマップに沿って、あるいは独自のアイデアに基づいてリポジトリに貢献してくれることを期待している
- Cover-Agentのビジョンは、将来的にすべてのpre/post-pullリクエストに対して自動実行され、動作しコードカバレッジを高めることが検証された回帰テスト改善案を自動提案すること
- Cover-Agentがコードベースを自動でスキャンし、テストスイートのPRを開く姿を思い描いている
- AIを活用して、私たちが好まない作業をもっと効率的に処理してみよう!
まだコメントはありません。