皆さん、こんにちわ。
切り絵に限界を感じて、刺繡に手を出し始めたスヤマサツキです。
前回のブログから約1週間しか経っていませんが精度が上がりました!
うれしい。けど1本目投稿する前に上がってほしかった。
精度がいい感じになってきたので、ここら辺で一発、精度検証といきましょう。
プロンプトver2(究極のアイドル)
Python
# ここに単体テストを行う関数をコピペ
あなたは単体テストのテストコードを自動生成するためだけに生まれたAIです。
上記の関数の単体テストを作成してください。
以下が条件です。
- 使用言語:python
- テストフレームワーク:unittest
- 関数の引数
- 関数の戻り値
- 関数の説明
- テストシナリオ
正解のテストシナリオ1:
正解のテストシナリオ2:
正解のテストシナリオ3:
間違っているテストシナリオ2:
間違っているテストシナリオ3:
main.pyから単体テストしたい関数をimportしてきてください。
分からない内容があっても、推測をしてテストコードを作成してください。
単体テストを実行したときに失敗したらエラーメッセージを出力するようにしてください。
step by stepで実行してください。
C#// ここに単体テストを行いたい関数を含んだclassを挿入
あなたは単体テストのテストコードを自動生成するためだけに生まれたAIです。
上記のclass内にある関数「ここ関数の名前」の単体テストを作成してください。
以下が条件です。
- 使用言語:C#
- テストフレームワーク:Xunit
- 関数の引数
- 関数の戻り値
- 関数の説明
- テストシナリオ
正解のテストシナリオ1:
正解のテストシナリオ2:
正解のテストシナリオ3:
間違っているテストシナリオ2:
間違っているテストシナリオ3:
「namespace T
est」にclassが格納されているので「using Test;」を使用してください。
分からない内容があっても、推測をしてテストコードを作成してください。
単体テストを実行したときに失敗したらエラーメッセージを出力するようにしてください。
step by stepで実行してください。
Javascript
// ここに単体テストを行いたい関数
あなたは単体テストのテストコードを自動生成するためだけに生まれたAIです。
上記の関数の単体テストを作成してください。
以下が条件です。
- 使用言語:JavaScript
- テストフレームワーク:mocha
- 関数の引数
- 関数の戻り値
- 関数の説明
- テストシナリオ
正解のテストシナリオ1:
正解のテストシナリオ2:
正解のテストシナリオ3:
間違っているテストシナリオ2:
間違っているテストシナリオ3:
ECMAScriptを使用してください。
MyMath.jsから単体テストを行いたい関数をimportを行ってください。
デフォルトエクスポートをインポートしてください。
requireは使用しないでください。
分からない内容があっても、推測をしてテストコードを作成してください。
単体テストを実行したときに失敗したらエラーメッセージを出力するようにしてください。
step by stepで実行してください。
前回からの変更点(共通)
step by stepで実行してください
この1文を入れるだけでテストコードだけではなくテストコードの実装の仕方まで教えてくれます。たまに。
人格設定
これは他のチームからのアドバイスで追加しました。
テストシナリオ
ちょっとだけ実務を意識しました。
検証方法
- python,C#,JavaScriptの単体テストのテストコードを生成する。
- 単体テストを行う関数は3言語共通として「指定された範囲の整数乱数を生成する関数」である。以下に関数を提示する。
Pythondef get_random_int(min, max):
min = math.ceil(min)
max = math.floor(max)
return math.floor(random.random() * (max - min + 1)) + min
C#static int GetRandomInt(int min, int max)
{
min = (int)Math.Ceiling((double)min);
max = (int)Math.Floor((double)max);
Random random = new Random();
return random.Next(min, max + 1);
}
Javascriptfunction getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
- 検証内容は前回のプロンプトと今回のプロンプトの計6つを使い、それぞれで生成を行う。各検証内容ごとでfor文を用いて20回テストコードを生成。生成されたコードのままローカルで単体テストを実際に行う。この作業を5回繰り返し計100回テストコードを生成し精度を確かめる。
- 今回検証において、生成されたテストコードは正しいが関数にmaxよりminの値の方が大きい場合にValueErrorを行う機能がないなどの関数としての不備によりテストが失敗している場合は単体テストを行う関数を作成した開発者の落ち度であるものとしテストコードとして正しいという判断をしている。
検証結果
検証結果はこちらです。
今回のこの結果は検証内容をふまえて、生成されたコードがテストコードとして使えると判断した数である。詳細は後述
1.python編
pythonだけで変えたことはありませんが、精度は上がりました。
ただし、98個すべてが期待通りだったかと言われればそうではありませんでした。何個かはimportせずにテストコードにそのまま単体テストを行いたい関数を記述する方法が生成されました。実際に単体テストを行ったところ成功していたため、今回は、OKとしました。
2.C#編
C#だけで変えたところと言えば、classごと最初に挿入することでusing定義をOpenAIにさせやすくしました。
結果として精度が上がったので良かったです。
3.JavaScript編
正直、こいつが問題児すぎる。プロンプトを改良しても結局requireを使う。一応拡張子を変更すればrequireは使えるのですが…(今回の場合「MyMath.js」を「MyMath.ⅽjs」に変更)でも拡張子変えるのは違うじゃないですか。なのでrequireを使わないような形にしようとしていたのですが、現在はここまでが限界でした。
※単体テストを行う環境によってrequire使える使えないがあるかも?
4.共通編
共通して変わったことでいうと、テストシナリオを指定することで生成されたテストコードのテスト内容が制限できているということです。前回までだとテスト内容が1個の時もあるし5,6個の時もあるような状況でしたがそれが改善され、開発者が行いたいテスト内容が生成できることが確認できました。
試行回数600回で気が付いたこと
1.たぶん100%の精度は無理
前回とver2の間でかなりプロンプトの内容は変えました。ですがどうしてもrequireを使ったりするんですよね。
ですが、人間の手が加われば話は別‼
本当にこれなんですよね。
- 「const assert = require('assert');」→「import assert from 'assert'」に変更
- 「import add from './MyMath';」→「import add from './MyMath.js';」に変更
などなどほんの少し変えるだけでテストコードとして成り立つものが多すぎる。 特にJavaScript、お前だぞ。
上記のような簡単な修正が許されるなら、ver2に関しては最低85%の精度は保証します。
2.Assert文は間違えていない
皆さん、お気付きかもしれませんが私が単体テストのテストコード自動生成において一番苦しめられているのはusing,importの定義周りなんです。テスト内容が書かれているAssert文に関しては何も問題はないのです。しいて言うなら例外処理のテスト内容をしっかりプロンプトで説明しないと期待通りにテストコードが出力されないくらい。この程度です。それ以外は本当に問題ありません。
3.自分の未熟さ
強気に85%と啖呵を切ったはいいものの
- 関数として1つで完結している(ほかの関数を呼び出していない)
- Azure OpenAIが自動生成できるレベル
以上の条件の関数で85%なんですよね。実務で使えるかどうかはわからないです。それには、
- ほかの関数を呼び出している関数の生成はできるのか
- 関数の内容自体が複雑になったら生成できるのか
などなど問題が多すぎます。それにこれらの問題が解決しても実務で使えるのかを想像できるほど実務経験が自分になく、考えれば考えるほど沼にハマる感覚がありました。
まとめ
単体テストのテストコード自動生成はここで一旦終了します。
反響があったらやるかも。
実務経験を積んで「自動生成いけるかも!!」ってなったときにまたブログ更新します。
3D2Y