25-05-18: テスト駆動×CICD×AI

結構前に考えてたやつ。

テスト駆動開発による組み込みプログラミングを読んで思い付いた。

テスト駆動×CICD×AI

方針

AIを活用した開発をしていく想定ですが,AI活用にはポイントがあると思っています。

AIの特徴は,ハルシネーション(知ったかぶり的なこと)をするリスクが常にある事。なので,人間がチェックして責任を持つ,というフローが絶対に必要だと思っています。

そこで,AIを活用する上では,どこに人間チェックを混ぜ込むかが重要だと思います。

人間のチェックタイミングで分類するなら,開発の方針は下記三点があると思います。

  • マイクロマネジメント:こまめにAIの出力を人間が”許可”する方針。例:Clineなど
  • マクロマネジメント:AI自身にチェックさせて,最後に一回だけ人間が確認する方針。例:Deep Researchなど。
  • ノーマネジメント(造語):人間チェックをしない方針。AIとの雑談など間違っていても良い場合。

次に,それを実装する方式について考える必要があります。

人間チェックをどうやるのか,チェックしやすい出力とは何かについてまとめると下記だと思います。

  • 向いている:文章(読み物),短い高級言語のコード…単体テストとか。
  • 向いていない:計算結果,集計結果,複雑な長いコード

単体テストは大概コードが読みやすいのでAIに生成させた結果を人間がレビューすることは容易だと思います。

#include "calculator.h"
#include <gtest/gtest.h>

/**
 * @brief Calculator::Add のテスト
 * Arrange: Calculatorインスタンスを用意する
 * Act: Add関数を呼び出す
 * Assert: 期待される結果と一致するか検証する
 */
TEST(CalculatorTest, Add_TwoPositiveNumbers_ReturnsSum) {
    // Arrange
    Calculator calc;
    int a = 3;
    int b = 4;

    // Act
    int result = calc.Add(a, b);

    // Assert
    EXPECT_EQ(result, 7);
}

アイデア:テスト駆動×AI

AIでまず単体テストを開発し,テスト駆動でテストをPASSするようにコードを開発する方針です。

flowchart TD
  A[要件定義] --> B1[AI:コード開発]
  A --> B2[AI:単体テストコード生成]

  B1 --> C1{人:コードレビュー}
  C1 -->|OK| D1[コードがビルド可能]
  C1 -->|NG| B1

  B2 --> C2{人:テストコードレビュー}
  C2 -->|OK| D2[テストコードFix]
  C2 -->|NG| B2

  D1 --> E{テスト実施}
  D2 --> E

  E -->|NG| B1
  E -->|PASS| F[コードFix]

効果は確認する必要があります。

  • テスト駆動をしないAI開発の方が高精度で高速である可能性がある
  • テスト駆動をしないAIなしの従来開発の方が高精度で高速である可能性がある

メリットとデメリットについてはこれらがあるかなと思っています。

  • メリット:
    • CI/CDツールによる効率化なリグレッションテストにスムーズに以降できる
    • 実際に動くコードによって動作を保証できる
  • デメリット:
    • テストを開発する必要があるので工数が増加する
    • AIで上手くコードを開発できないリスクがある

とりあえず一旦,やってみる必要があるかなと思います。

組み込み

見た目(GUIなど)で分からない機能はテストコードで確認することになると思います。逆にテストコードがあれば機能が分かるので,ドキュメントの一部としても見ることが出来ます。

そういう意味でも,例え品質目標として定義されていなくても,内部状態が分かるという意味で組み込みは出来る限り読んで分かる単体テスト・結合テストを整備するのが理解の意味で良いように思います。もちろん開発スピードとバランスを取る必要はあります。

趣味開発をするうえではスピードの制約はないので(モチベーションの制約はありますが)自作OSを作る上でできるだけテストをこのしていきたいと思います。

※テストは単体テスト用のフレームワークGoogleTestを使うことを想定していますが,結合テストも何割かは作ろうと思います。