見出し画像

自作ゲームのコードで見る、ChatGPTのテストケース生成

このエントリーはAkatsuki Advent Calendar 2022の12日目の記事です。

昨日は yuyu さんの「今からでも遅くない!最新のUnityエディタ拡張を知ろう 〜 UIElementsのすすめ 〜」でした。
Unityのエディタ拡張ってIMGUIは毎フレーム描画していたんですね。UIも毎フレーム描画が普通だよねという感覚はゲームらしいといえばらしいのですが、エディタ側でもそうなっているのはなかなかゴツい...

はじめに

ChatGPT、とても人気ですね。動くWebアプリを対話的に作れてしまったりLinux のターミナルとして動かしてみたり(?)、みんなで面白いものを見つけてワイワイするのは楽しいです。
さて、今回は自作ゲームのコードを実例にして、ChatGPTさんにテストケースを生成してもらい、まあまあ実用的な検証観点を得ることができました。一緒に見ていきましょう。

検討する仕様

フェアリティアというブラウザゲームがあります。自作です。
1~10までの数値が書かれたカードを数値が大きくなっていくように重ねていき、^ 模様のカードを出すと消せる、というソリティアライクなゲームです。
複数の操作キャラクターが存在し、それぞれに決められた追加ルールを目的としてゲームが進行します。

下の画像のキャラはアリティといい、カードを4枚 または 8枚ぴったりで出すことによって勝利点を得ることができます。カード枚数をうまく調整できるように、空き枠のマネジメントをしていくキャラクターです。

ここで左から3つ目の枠に ^ を出すと4枚になり、1ポイント獲得

アリティさんのスコアはカード4枚の束ひとつにつき1点、8枚の束ひとつにつき3点です。スコア計算には、シンプルにこんな関数を用意していました。

arityStyleScore() {
  const lengths = this.cardLengthList();
  const fours = lengths.filter((x) => x === 4).length;
  const eights = lengths.filter((x) => x === 8).length;
  return fours + eights * 3;
}

スコア計算をするクラスからそのまま関数定義を丸々コピーしているので、cardLengthList() という関数の正体がわかりませんね。この文脈無しでテストケースを考えることができるんでしょうか。テスト容易性を高めるのであればcardLengthList を引数に取る純粋な関数にしたほうが良さそうですが、今回はこのままChatGPTさんに食べさせてみましょう。

プロンプト

arityStyleScoreのテストケースを考える際、漏れがちなテストケースにはどのようなものがあるでしょうか?

  arityStyleScore() {
    const lengths = this.cardLengthList();
    const fours = lengths.filter((x) => x === 4).length;
    const eights = lengths.filter((x) => x === 8).length;
    return fours + eights * 3;
  }

出力

・複数のデータを引数に取る場合の動作テスト
・lengthsの内容が空の場合の動作テスト
・lengthsの内容が負の値を含む場合の動作テスト
・lengthsの内容が文字列を含む場合の動作テスト
・lengthsの内容が2,3,5,6,7を含む場合の動作テスト
・lengthsの内容が配列以外のものを含む場合の動作テスト

ChatGPT

かしこいですね。lengths によって挙動を変えている関数であることを理解して、振る舞いにどんなパターンがあるかを検討しているように見えます。
ChatGPTが解釈しやすいようにコードをある程度改変しなければならないのを覚悟していたので、素のままでこの回答を得られたのはかなり驚きました。

ちなみに「テストケースを列挙してください」というプロンプトにした場合、入力値のパターンと期待結果のみを列挙してしまいます。それでもまずまず使えるのですが、観点を問うと日本語で答えてくれます。実装時の考慮漏れや検討すべきエッジケースを発見する際にはこちらのほうが嬉しいですね。

コードでなくても良い

今回は実装をそのまま投げつけましたが、実装仕様レベルまで詳細に説明すれば自然言語で記述された仕様に対しても観点を列挙することができます。

arityStyleScoreはjavascriptの関数です。この関数のテストケースを考えるさいの観点を5つ以上列挙してください。
・arityStyleScoreはポイントを計算する関数である
・arityStyleScoreは0以上9未満の任意長の自然数のリストを引数に取る
・arityStyleScoreは引数に含まれる数値4ひとつにつき、1ポイント加算する
・arityStyleScoreは引数に含まれる数値8ひとつにつき、3ポイント加算する

(最初2つだけ観点を挙げて終了してしまったので、5つ以上出すようプロンプトに追加しています)

・arityStyleScoreは引数に含まれる数値5ひとつにつき、0ポイント加算する
・arityStyleScoreは引数が空リストである場合、0ポイントを返す
・arityStyleScoreは引数に含まれる数値が9以上である場合、0ポイントを返す
・arityStyleScoreは引数に含まれる数値が小数点以下を含む場合、0ポイントを返す
・arityStyleScoreは引数に含まれる文字列型のデータを受け入れない
・arityStyleScoreは引数に含まれる数値が文字列表記である場合、0ポイントを返す

ChatGPT

だいたい似たようなエッジケースの検討をしてくれていますね。

まとめ

ChatGPTに直接コードを書かせる場合は生成されたコードが正しいか注意してレビューする必要があり、なかなか神経を使ってしまいます。その点テストケースの観点出しなら「漏れそうなものを補強する」という点でAIの提案を受けるメリットだけを享受できます。
入力が自然言語の場合も動作するため、仕様策定時点でのエッジケースの検討にも使えるかもしれません。現実的な活用法がかなりイメージしやすいのではないでしょうか。
あ、フェアリティアは楽しいゲームにできた自信がありますのでぜひ遊んでくださいね!

明日は Shintaro Ishimine さんがなにか書いてくれます。たのしみですね!


この記事が気に入ったらサポートをしてみませんか?