連載「業務SEのための仕様駆動開発」第3回
AIが書いたテストは全部通る。でも、安心できない
AIにプログラムを書かせると、それらしいコードがすぐに出てきます。テストもAIに書かせると、全部通ります。
それなのに、なぜか安心できない。そんな経験はないでしょうか。
その不安は、たぶん正しいです。問題は、AIにテストを書かせることではありません。書かせるタイミングと、渡す材料です。
結論:テスト仕様書は、実装の前に、AIに作らせる
テスト仕様書とは、「何をしたら、どうなれば合格か」を並べた一覧です。
私は、これを自分の手では書きません。AIに作らせています。 ただし、プログラムを作らせる前にです。
AIに渡す材料は2つです。
- 仕様:こう動くこと(目的確定メモや設計書に書いたもの)
- やってはいけないこと:入力のチェックなど、もともと決まっている禁止事項
AIは、この2つを掛け合わせてテスト仕様書を作ります。
実装の後に作らせると、何でも通ってしまう
先に、タイミングの話をします。第1回で例にした「受注CSVを在庫システムに取り込む」仕組みで考えます。
この取り込みプログラムに、見出し行だけの空っぽのCSV(0件)を読ませると、エラーで止まってしまうとします。本当は「0件でした」と表示してほしいところです。
プログラムを作った後で、AIにテストを書かせるとどうなるか。私の経験では、AIはできあがったプログラムに合わせてテストを書きがちです。すると、「0件のCSVなら、エラーが出ること」を確かめるテストができてしまいます。今の動きをなぞっているので、テストは通ります。でも、欲しかった動きではありません。
プログラムより先に、仕様からテスト仕様書を作らせれば、こうはなりません。仕様に「0件なら『0件』と表示する」とあれば、エラーで止まるプログラムはテストで落ちます。
テストが確かめるべきなのは、「プログラムが、今のプログラムどおりに動くこと」ではなく、「仕様どおりに動くこと」です。だから、テスト仕様書は、プログラムより先に作らせます。
テスト仕様書は「仕様 × やってはいけないこと」でできている
次に、材料の話です。
業務システムには、たいてい「やってはいけないこと」が最初から決まっています。代表的なのは、入力のバリデーション(入力チェック)です。受注CSVの例なら、たとえば次のようなものです(仮の例)。
- 商品コードは、商品マスタにあるものだけ
- 数量は、1以上の整数
- 単価は、取り込みのときに直さない(修正は人が行う。第1回で決めた「今回やらないこと」)
仕様の「受注CSVを取り込む」に、これを1つずつ掛け合わせると、テストの行ができます。
| 仕様 | × やってはいけないこと | → できるテスト |
|---|---|---|
| 受注CSVを取り込む | 商品コードはマスタにあるものだけ | 存在しない商品コードの行を混ぜる → その行は取り込まれず、行番号と理由が一覧に出る |
| 受注CSVを取り込む | 数量は1以上の整数 | 数量が0の行を混ぜる → その行は取り込まれず、行番号と理由が一覧に出る |
| 受注CSVを取り込む | 単価は直さない | 単価が間違っている行を混ぜる → 単価は直されず、CSVのとおりに取り込まれる |
仕様1つに、やってはいけないことがいくつも掛かります。仕様が10個、やってはいけないことが20個あれば、組み合わせはすぐに数十行になります。これを漏れなく並べるのは、人よりAIのほうが得意です。
特に、3行目のような「やってはいけないこと」は大事です。AIは親切なので、頼んでいない改善までしてしまうことがあります。仕様だけからテストを作ると、こうした余計な動きは見逃されます。
型:やってはいけないこと一覧のテンプレート
材料のうち、仕様は、第1回・第2回で紹介した目的確定メモと設計書です。もう1つの材料が、やってはいけないことの一覧です。
この一覧は、案件ごとに一から作るものではありません。業務システムなら、中身はどの案件でもほとんど同じです。一度作れば、使い回せます。 そこで、どの案件でも使う「共通」と、案件ごとに足す「この案件だけ」の2つに分けておきます。コピーして使ってください。
# やってはいけないこと一覧
## 共通(どの案件でも使い回す)
### 入力のチェック(受け付けてはいけない値)
- 必須:空欄を受け付けない
- 型:数値の欄に文字を、日付の欄に日付でない値を受け付けない
- 長さ:決めた桁数・文字数を超える値を受け付けない
- 範囲:決めた範囲の外(マイナス、0、上限超え)を受け付けない
- 存在:マスタにないコードを受け付けない
- 重複:同じデータの二重登録を受け付けない
### 権限
- 権限のない人は、実行も閲覧もできない
### データ
- 既存のデータを、断りなく書き換えたり消したりしない
- テーブル定義を変えない
## この案件だけ
- (例)CSVの中身の誤り(単価違いなど)は直さない。修正は人が行う
- (例)取り込みを実行できるのは、取り込み担当のアカウントだけ
「共通」は、最初から完璧にしなくてかまいません。まず作って、使ってみる。 テストやバグで足りないものが見つかったら、そのつど足していきます。案件を重ねるほど一覧が育ちます。前の案件で足したものは、次の案件では最初から入っています。
「この案件だけ」は、第1回の目的確定メモで書いた「制約」が元になります。
人が確かめるのは、材料のほう
AIが作ったテスト仕様書を、私が1行ずつ確かめることは、ほとんどありません。確かめるのは、材料のほうです。
- 仕様に、決めたことが全部書かれているか
- やってはいけないこと一覧に、抜けがないか
材料が正しければ、掛け合わせはAIが漏れなくやってくれます。逆に、材料に抜けがあれば、テストにも同じ抜けが出ます。さっきの0件の例も、仕様に「0件ならどうするか」が書かれていなければ、テストには出てきません。テストを増やしたいときも、テスト仕様書を直接直すのではなく、材料を直して、AIに作り直させます。やってはいけないこと一覧に足したものは、次の案件でもそのまま効きます。
私の場合:テスト仕様がないと、区別がつかなくなる
私の経験では、テスト仕様をつくらずに進めると、バグが出たときに、それが仕様から来たものなのか、本当のプログラムのバグなのか、区別しにくくなります。
「どうなれば合格か」がどこにも書かれていないので、その動きが誤りなのかどうか自体が、はっきりしないからです。仕様の問題をプログラムの修正でしのいだり、プログラムの問題を「そういう仕様だった」で片づけたりすることにもなりかねません。
エンジニアの方にはおなじみの考え方だと思います。ウォーターフォールでは、テストは設計に対応させてつくります。作るのがAIになっても、この順番はそのまま使えます。
まとめ
- 実装の後にAIにテストを書かせると、今のプログラムをなぞるだけになりやすい
- テスト仕様書は、実装の前に、AIに作らせる
- 材料は「仕様」と「やってはいけないこと一覧」の2つ。AIが掛け合わせてテストの行を作る
- やってはいけないこと一覧は、一度作って使い回し、足りないものを足して育てる
- 人が確かめるのは、テスト仕様書ではなく材料のほう
次回は、業務でAIを使う前に確認しておきたい6つのことを、チェックリストの形で紹介します。
連載「業務SEのための仕様駆動開発」
一覧はこちら → https://qiita.com/sha44444/stocks/3c9167054a4a82837bb3
この連載では、仕様駆動開発の「型」を1回に1つずつ紹介しています。
5つの工程を実案件でどう回しているか(各工程でAIに渡す依頼文、変更が入ったときの回し方、通しの実例)は、1冊の本にまとめました。第1章は無料で読めます。
→ https://zenn.dev/shin4/books/31499dd20de8ac