テスターちゃん【4コマ漫画】

ソフトウェアテストの用語、やり方などを4コマ漫画でわかりやすく説明する(予定の)ブログです。脱線も多いです。



o1にテスト観点を出してもらった結果がエグい

o1(OpenAI o1)はGPTの冠が外れたLLMのモデルです。

o1は思考時間をとることにより、4oよりも高度な推論が可能となっているモデルです。

数学やコーディングのテストにおいて4oのスコアを大きく引き離しています。

そのo1-previewを用いてサンプルアプリのテスト観点を出してもらい、私が出したテスト観点と比較を行ってみました。

 

 

話を進める前にテストについて大事なこと

テストにおいて仕様通り動くかのチェックはとても大切です。

ですが、それだけではテストは足りません。

仕様には書いていない考慮漏れで問題が発生する、端末の画面サイズで問題が発生する、他のシステムと連携で問題が発生してしまうといったことがあります。

数年IT界隈にいる人でしたら、そういったところで本番障害に遭遇して苦労した経験があるかと思います。

仕様通り動くかのチェックは最低限のテスト活動であり、加えて仕様外に目を向け「発想」する必要があります。

尊敬する兄貴分の池田さんの資料より

テストとは、エラーをみつけるつもりでプログラムを実行する過程である

by Glenford J. Myers (ソフトウェア・テストの技法 第2版)

なぜこの話をしたかというと、これから話すo1の結果に関係があるからです。

 

結論から

  • 結果
    • o1-previewでは62.7% (42件/全67件)のテスト観点を出せた (全体 = 僕の出した観点とo1が出した観点のマージ後の合計)
    • o1-previewでは機能テストにおいては仕様に書かれた内容までである
    • o1-previewではユーザビリティ、セキュリティ、互換性などの~lity系の観点を出せる
  • o1活用の考え
    • o1にベースとなるテスト観点を出してもらって、人間が暗黙知、経験からテスト観点を追加しテストを作っていく
    • 仕様確認である動作チェック部分はo1で作ってしまいスモークテストとする。並行して人間が不足観点部分のテストを作る(o1と人間の分業)

 

お題と僕が出したテスト観点

speakerdeck.com

この仕様書を使って、私もテスト観点を出してみました。

私はこうやってマインドマップでテストすることを出す!

↓結果

o1にテスト観点を出してもらう

与えたプロンプトは以下です。

このアプリで何をテストしたらいいかのテスト観点をMindmapで出してください。Mindmapはmermaid形式で出力してください。
不明な情報は私に質問を返してください。

割り勘アプリを開発します。
飲み会の時などに使いたくなるものです。
「合計金額」と「割り勘したい人数」から一人当たりの金額と不足金額(割り切れなかった分のお金)を出します。
「金額を固定したい人数」は、例えば遅れてきた人は1000円ね、としたい場合に使用します。

合計金額……半角6桁。合計金額。最低金額は0円
割り勘したい人数 ……半角2桁。割る人数。最低1人
金額を固定したい人数……半角2桁。割り勘に含めず固定した金額を払う人数。未入力の場合0として扱う
固定する金額……半角6桁。固定した金額を払う人が払う金額。金額を固定したい人数が未入力の時は非アクティブ。

計算ボタン……押すと一人当たりの金額と不足額を計算する
 一人の金額 ……半角6桁。割り勘した一人当たりの金額。カンマ区切り
不足金額…… 半角6桁。割り勘したときのあまりの金額。

ちなみにmermaid記法はマークダウンでマインドマップフローチャート、シーケンス図などが書ける方法です。AIでテスト観点を列挙するだけならマインドマップにする必要はないなといまさら思っています。

 

結果は以下です。

mindmap
  根*1
    入力値の検証
      合計金額
        - 最小値 (0円)
        - 最大値 (999,999円)
        - 桁数 (半角数字6桁)
        - 無効な入力
          - 負の数
          - 文字列
          - 特殊文字
      割り勘したい人数
        - 最小値 (1人)
        - 最大値 (99人)
        - 桁数 (半角数字2桁)
        - 無効な入力
          - 負の数
          - 0
          - 文字列
          - 特殊文字
      金額を固定したい人数
        - 未入力時は0として扱う
        - 桁数 (半角数字2桁)
        - 無効な入力
          - 負の数
          - 文字列
          - 特殊文字
      固定する金額
        - 非アクティブ条件
          - 金額を固定したい人数が未入力時
        - 桁数 (半角数字6桁)
        - 無効な入力
          - 負の数
          - 文字列
          - 特殊文字
    機能テスト
      計算ボタン
        - 正しい計算結果
          - 一人当たりの金額
          - 不足金額
        - 固定金額の人がいる場合の計算
        - 入力が無効な場合の動作
          - エラーメッセージの表示
          - 計算を行わない
      フィールドの状態
        - 非アクティブ条件
          - 金額を固定したい人数が未入力時、固定する金額は非アクティブ
    ユーザーインターフェース
      表示フォーマット
        - 一人当たりの金額
          - カンマ区切り
        - 不足金額
          - カンマ区切り
      エラーメッセージ
        - 無効な入力時の適切な表示
        - フォーカスの移動
    ユーザビリティ
      - 使いやすさ
      - 入力しやすさ
      - ボタンやフィールドのレイアウト
    パフォーマンス
      - 計算のレスポンスタイム
      - 大量入力時の動作
    セキュリティ
      - 不正入力への耐性
      - データの保護
    互換性
      - 異なるデバイスでの動作
      - 異なるブラウザでの表示

mermaid記法とは少し違いましたが、テスト観点としては良さそうなものが出力されました。

生成のたびにパフォーマンスやユーザビリティなどが抜けたりなど、結果は都度変わります。

フォーカスを変えながら(機能に注目、~性に注目など)何度か観点を出してマージしてもよいかもしれません。今回はまとめてテスト観点を出力させた状態で進めます。

 

o1が出したテスト観点を確認

半角6桁、という内容から999,999円の境界値を出すことができています。

ただ1,000,000円の境界値は出ません。

無効な入力も出してくれるのはGoodです。試したほうがよさそうな主要なカテゴリは出ています。

 

割り勘したい人数は1人からなので、無効の値に0が入っているのはGoodです。

 

固定する金額も非アクティブの条件は仕様に明記しているので出ています。

動作チェックであればアクティブである条件も見ておきたいところです。

固定人数を入れた正常系の処理時に通るから不要である、という考え方もできそうです。

 

機能テストのカテゴリは、イレギュラーなパターンは含まれていません。

イレギュラーなパターンは、同値分割から考えられそうな無効な値などではなく、固定した人数のお金が合計金額を上回ってしまう場合はどうなるかといった、想像して「こういう問題が起きそうだな」というパターンです。

 

ユーザビリティやパフォーマンス、セキュリティ、互換性の観点が入ってきたのはExcellentです。

このアプリにどこまで求めるかによって剪定する観点になるかと思いますが、まずはこれらが出せていることが素晴らしいです。

 

私が出したテスト観点と比較

o1が出したテスト観点と私が出したテスト観点をマージしたものが以下です。

記載した言葉の意味は以下です。

  • OK……私もo1も双方が出した観点
  • ADD……私が出したが、o1が出していない観点
  • None……私が出せなかったが、o1が出した観点
```mermaid
mindmap
  root*2
    入力値の検証
      合計金額
        最小値 (0円) OK
        最大値 (999,999円) OK
        桁数 (半角数字6桁) OK
        無効な入力
          負の数 OK
          文字列 OK
          特殊文字 OK
          e ADD
          小数 ADD
          カンマ ADD
          01みたいな数字 ADD
          無(null) ADD
          -0を入れたらどうなる? ADD
        攻撃
            クソデカ数字いれたら壊れない? ADD
      割り勘したい人数
        最小値 (1人) OK
        最大値 (99人) OK
        桁数 (半角数字2桁) OK
        無効な入力
          負の数 OK
          0 OK
          文字列 OK
          特殊文字 OK
        攻撃
            割り勘したい人数が合計金額を超えた場合 ADD
        計算
            割り切れる場合 ADD
            割り切れない場合 ADD
      金額を固定したい人数
        未入力時は0として扱う OK
        桁数 (半角数字2桁) OK
        無効な入力
          負の数 OK
          文字列 OK
          特殊文字 OK
      固定する金額
        非アクティブ条件
          金額を固定したい人数が未入力時 OK
        アクティブ条件
            固定したい人数入力済み ADD
        固定したい人数が無効の値だったらどうなるの? ADD
        桁数 (半角数字6桁) OK
        無効な入力
          負の数 OK
          文字列 OK
          特殊文字 OK
    計算ボタン
        攻撃
            全部何も入力していない状態でクリック ADD
            入力ボックスでエンターで計算される?されない? ADD
            連打 ADD
        何度も繰り返して計算しても大丈夫? ADD
    機能テスト
      計算ボタン
        正しい計算結果
          一人当たりの金額 OK
          不足金額 OK
        固定金額の人がいる場合の計算 OK
        固定のみ
            合計金額アリ ADD
            合計金額なし ADD
        入力が無効な場合の動作
          エラーメッセージの表示 OK
          計算を行わない None
      フィールドの状態
        非アクティブ条件
          金額を固定したい人数が未入力時、固定する金額は非アクティブ OK
      バグを出すためのテスト
        人数を入れてアクティブにして入力後に人数を抜いて非アクティブにしたらどうなるの? ADD
        合計金額を固定する金額 * 人数が合計金額を超えたらどうなるの? ADD
        合計金額を固定する金額 * 人数は超えないが、割り勘したい人数で割った結果、合計金額が1円を切る ADD
      表示フォーマット
        一人当たりの金額
          カンマ区切り OK
        不足金額
          カンマ区切り OK
      エラーメッセージ
        無効な入力時の適切な表示 OK
        フォーカスの移動 None
      使いやすさ None
      入力しやすさ None
      ボタンやフィールドのレイアウト None
    パフォーマンス
      計算のレスポンスタイム OK
      大量入力時の動作 None
    セキュリティ
      不正入力への耐性 None
      データの保護 None
    互換性
      異なるデバイスでの動作 OK
      異なるブラウザでの表示 OK
      画面サイズ
        普通 ADD
        小さい ADD
    ブラウザ
      リロード ADD
      戻る ADD
```

 

集計結果は以下です。

  • OK……34件
  • ADD……25件
  • None……8件
  • OK + ADD + None(つまり全件) = 67件
  • OK + None(つまりo1が出した観点)……42件(62.7%)
  • OK + ADD(つまり私が出した観点)……59件(88.1%)

o1ではどういったテスト観点が出せなかったか

主に「この辺どうなるんだろう?」という仕様に載っていないところは出せません。

「発想」はまだ人間の領域のようです。

こういった部分は実務では企画や聞いて明確化してもらう、実際に試してみてどうなるか確認する場所となります。

 

お金の計算ですと、切り上げ、切り捨てどちらの処理かで支払う額が変わってきます。

割り勘程度のアプリですと大したことありませんが、大きなお金を扱うシステムだと要注意です。端数をどうにかしていた、という悪事を聞いたことがあります。

もしかしたら割り勘でも1円の誤差で怒る人だっているかもしれません。

 

意地悪テストも出せません。

例えば今回であれば、固定人数が未入力だと固定金額は非アクティブです。

けれど固定人数を入力し固定金額をアクティブにした上で固定人数を抜いてしまったらどうなるのでしょうか?

表示だけがおかしくなるならいいですが、計算結果に何かしら影響があると困ります。

「そういう処理はしていない」という人もいますが、いざ試してみると「あれ!?なんでそうなった!?」があったりするものです。

あとは、例えば固定した人数の金額が合計を超えてしまう、超えてしまわなくても計算結果割り勘の結果が1円を切ってしまったらどうなるのだろう?といった部分です。

 

テスト設計レベル(パターン出しといったところ)にはなってしまいますが、「普通の割り勘のみ使うパターン」「普通の割り勘と固定を使うパターン」があるのならば、機械的に考えると「固定のみのパターン」と「何も入力しないパターン」が考えられます。

 

実際にテストを作っていく際は「本当にそのテスト観点はテストしたほうがいいのか」と優先度を考えて、テスト観点を「剪定」する必要があります(テスト工数は有限のため)。私が出した観点だと「連打」も入っていたりしますが、何か登録が発生しないのであれば剪定してしまうと思います。

 

私はどういった観点が出せなかったか

ユーザビリティ、セキュリティといったところが出せていませんでした。

セキュリティであればweb系はXSSはやっておいてよいでしょう。

あとサーバーを介すようなアプリだった場合はリクエスト数による負荷テストも考えられるかもしれません。

 

o1が出した観点でテスト項目を作ってもらった結果

せっかくなのでテスト項目まで作ってもらいました。

"項目番号","大項目","中項目","小項目","前提条件","テスト手順","期待結果"
"TC001","入力値の検証","合計金額","最小値","アプリが起動している","合計金額に0を入力する","エラーなく受け付ける"
"TC002","入力値の検証","合計金額","最大値","アプリが起動している","合計金額に999999を入力する","エラーなく受け付ける"
"TC003","入力値の検証","合計金額","最大値超過","アプリが起動している","合計金額に1000000を入力する","エラーメッセージを表示する:「合計金額は最大999,999円までです」"
"TC004","入力値の検証","合計金額","負の数入力","アプリが起動している","合計金額に-1を入力する","エラーメッセージを表示する:「合計金額は0円以上で入力してください」"
"TC005","入力値の検証","合計金額","文字列入力","アプリが起動している","合計金額に文字列「abc」を入力する","エラーメッセージを表示する:「合計金額は半角数字で入力してください」"
"TC006","入力値の検証","合計金額","特殊文字入力","アプリが起動している","合計金額に特殊文字「!@#」を入力する","エラーメッセージを表示する:「合計金額は半角数字で入力してください」"
"TC007","入力値の検証","合計金額","桁数超過","アプリが起動している","合計金額に7桁の数字「1000000」を入力する","エラーメッセージを表示する:「合計金額は6桁以内で入力してください」"
"TC008","入力値の検証","割り勘したい人数","最小値","アプリが起動している","割り勘したい人数に1を入力する","エラーなく受け付ける"
"TC009","入力値の検証","割り勘したい人数","最大値","アプリが起動している","割り勘したい人数に99を入力する","エラーなく受け付ける"
"TC010","入力値の検証","割り勘したい人数","最大値超過","アプリが起動している","割り勘したい人数に100を入力する","エラーメッセージを表示する:「割り勘人数は最大99人までです」"
"TC011","入力値の検証","割り勘したい人数","負の数入力","アプリが起動している","割り勘したい人数に-1を入力する","エラーメッセージを表示する:「割り勘人数は1以上で入力してください」"
"TC012","入力値の検証","割り勘したい人数","文字列入力","アプリが起動している","割り勘したい人数に文字列「abc」を入力する","エラーメッセージを表示する:「割り勘人数は半角数字で入力してください」"
"TC013","入力値の検証","割り勘したい人数","特殊文字入力","アプリが起動している","割り勘したい人数に特殊文字「!@#」を入力する","エラーメッセージを表示する:「割り勘人数は半角数字で入力してください」"
"TC014","入力値の検証","割り勘したい人数","0入力","アプリが起動している","割り勘したい人数に0を入力する","エラーメッセージを表示する:「割り勘人数は1以上で入力してください」"
"TC015","入力値の検証","金額を固定したい人数","未入力時の扱い","アプリが起動している","金額を固定したい人数を未入力にする","システムは0として扱う"
"TC016","入力値の検証","金額を固定したい人数","負の数入力","アプリが起動している","金額を固定したい人数に-1を入力する","エラーメッセージを表示する:「金額を固定したい人数は0以上で入力してください」"
"TC017","入力値の検証","金額を固定したい人数","文字列入力","アプリが起動している","金額を固定したい人数に文字列「abc」を入力する","エラーメッセージを表示する:「金額を固定したい人数は半角数字で入力してください」"
"TC018","入力値の検証","金額を固定したい人数","特殊文字入力","アプリが起動している","金額を固定したい人数に特殊文字「!@#」を入力する","エラーメッセージを表示する:「金額を固定したい人数は半角数字で入力してください」"
"TC019","入力値の検証","固定する金額","未入力時の扱い","金額を固定したい人数が入力されている","固定する金額を未入力にする","エラーメッセージを表示する:「固定する金額を入力してください」"
"TC020","入力値の検証","固定する金額","負の数入力","金額を固定したい人数が入力されている","固定する金額に-1000を入力する","エラーメッセージを表示する:「固定する金額は0円以上で入力してください」"
"TC021","入力値の検証","固定する金額","文字列入力","金額を固定したい人数が入力されている","固定する金額に文字列「abc」を入力する","エラーメッセージを表示する:「固定する金額は半角数字で入力してください」"
"TC022","入力値の検証","固定する金額","特殊文字入力","金額を固定したい人数が入力されている","固定する金額に特殊文字「!@#」を入力する","エラーメッセージを表示する:「固定する金額は半角数字で入力してください」"
"TC023","機能テスト","計算ボタン","正しい計算結果","正しい入力値が全て入力されている","計算ボタンを押す","正しい一人当たりの金額と不足金額が表示される"
"TC024","機能テスト","計算ボタン","固定金額の考慮","固定金額の人がいる設定で正しい入力値が全て入力されている","計算ボタンを押す","固定金額の人を除いた割り勘金額と不足金額が正しく計算される"
"TC025","機能テスト","計算ボタン","無効な入力時の動作","合計金額に無効な値が入力されている","計算ボタンを押す","エラーメッセージが表示され、計算は行われない"
"TC026","機能テスト","計算ボタン","無効な入力時の動作","割り勘したい人数に無効な値が入力されている","計算ボタンを押す","エラーメッセージが表示され、計算は行われない"
"TC027","機能テスト","フィールドの状態","非アクティブ条件","金額を固定したい人数が未入力または0の時","固定する金額フィールドが非アクティブであることを確認する","固定する金額フィールドが入力不可である"
"TC028","機能テスト","フィールドの状態","アクティブ条件","金額を固定したい人数が1以上の時","固定する金額フィールドがアクティブであることを確認する","固定する金額フィールドが入力可能である"
"TC029","ユーザーインターフェース","表示フォーマット","一人当たりの金額の表示","計算結果が表示された後","一人当たりの金額がカンマ区切りで表示されていることを確認する","金額がカンマ区切りで正しく表示されている"
"TC030","ユーザーインターフェース","表示フォーマット","不足金額の表示","計算結果が表示された後","不足金額がカンマ区切りで表示されていることを確認する","金額がカンマ区切りで正しく表示されている"
"TC031","ユーザーインターフェース","エラーメッセージ","適切な表示","無効な入力値がある状態","計算ボタンを押す","対応するエラーメッセージが表示される"
"TC032","ユーザーインターフェース","エラーメッセージ","フォーカスの移動","エラーメッセージが表示された後","エラーのある入力フィールドにフォーカスが移動することを確認する","エラーのある入力フィールドにフォーカスが移動する"
"TC033","ユーザビリティ","使いやすさ","ボタン配置","アプリが起動している","ボタンやフィールドのレイアウトを確認する","直感的で使いやすい配置になっている"
"TC034","ユーザビリティ","入力しやすさ","キーボード操作","アプリが起動している","タブキーで入力フィールド間を移動する","入力フィールド間をスムーズに移動できる"
"TC035","パフォーマンス","計算のレスポンスタイム","正しい入力値が全て入力されている","計算ボタンを押す","計算結果が即座に表示される(レスポンスが速い)"
"TC036","パフォーマンス","大量入力時の動作","合計金額に999999を入力する","計算ボタンを押す","システムが遅延なく応答する"
"TC037","セキュリティ","不正入力への耐性","スクリプト入力","入力フィールドに「<script>alert('test')</script>」を入力する","スクリプトが実行されず、エラーメッセージが表示される"
"TC038","セキュリティ","データの保護","個人情報の入力","入力フィールドに個人情報を入力する","データが外部に漏洩しない(ただし、個人情報は入力しない想定)"
"TC039","互換性","デバイス間の動作","スマートフォンでの操作","スマートフォンでアプリを起動し、操作する","正しく表示・動作する"
"TC040","互換性","デバイス間の動作","タブレットでの操作","タブレットでアプリを起動し、操作する","正しく表示・動作する"
"TC041","互換性","デバイス間の動作","PCでの操作","PCでアプリを起動し、操作する","正しく表示・動作する"
"TC042","互換性","ブラウザ間の動作","Chromeでの操作","Chromeでアプリを起動し、操作する","正しく表示・動作する"
"TC043","互換性","ブラウザ間の動作","Firefoxでの操作","Firefoxでアプリを起動し、操作する","正しく表示・動作する"
"TC044","互換性","ブラウザ間の動作","Safariでの操作","Safariでアプリを起動し、操作する","正しく表示・動作する"
"TC045","入力値の検証","全角入力の対応","全角数字入力","アプリが起動している","合計金額に全角数字「123456」を入力する","エラーメッセージを表示する:「半角数字で入力してください」"
"TC046","入力値の検証","合計金額","全角文字入力","アプリが起動している","合計金額に全角文字「あいう」を入力する","エラーメッセージを表示する:「合計金額は半角数字で入力してください」"
"TC047","機能テスト","計算ボタン","合計不一致の検証","固定する金額が合計金額を超える場合","計算ボタンを押す","エラーメッセージを表示する:「固定金額は合計金額以下で入力してください」"
"TC048","機能テスト","計算ボタン","人数不一致の検証","割り勘したい人数と金額を固定したい人数の合計が不合理な場合","計算ボタンを押す","エラーメッセージを表示する:「人数の合計が正しくありません」"
"TC049","入力値の検証","固定する金額","合計金額超過","金額を固定したい人数が入力されている","固定する金額に合計金額+1を入力する","エラーメッセージを表示する:「固定する金額は合計金額以下で入力してください」"
"TC050","ユーザビリティ","エラーメッセージ","内容の明確さ","無効な入力値がある状態","エラーメッセージの内容を確認する","エラー原因が明確に伝わるメッセージが表示されている"

……見づらいですね。

 

テストクラスタからは怒られる大中小項目で出してもらいました。

最低限動作しているか仕様をなぞるテストとしては良しに見えています。

(エラーメッセージは勝手に作られてしまっているけど)

僕ならスモークテストでこの項目を通す、は戦術として悪い手ではないと考えます。

このテスト項目を通せば、このアプリのそれこそ60%程度はチェックができそうです。

文字列だけ細かい、互換性のテストはザックリ、なども見て取れますが、ここは観点ごとに区切って生成しながらテストを詳細化するという手もとれそうだと感じます。

 

これらの結果からo1のテストの活用について

細かいテスト観点が出せないからo1は使えないとするのはあまりに0/1思考すぎます。

このサンプルアプリでいえば60%程度は出せています。

仕様に書かれている場所はCPM法(仕様書をコピペしてテスト項目とする)より出せています。

o1にベースとなるテスト観点を出してもらい、人間がそれらをもとにこれまでの経験、プロジェクトの暗黙知から「発想」してテスト観点を追加するのは手です。

私が出せなかった観点も含まれていましたので、ベースとすることでテスト観点の補間もできるでしょう。

また、o1が出したテスト観点から生成されたテスト項目はスモークテストレベルには使えそうに見えています。

なので、まずはテスト項目を出してしまって、開発側に「この項目は通るようにお願いします」というようにTDD的に使うこともできるかもしれません。

残念ながら仕様をなぞるチェックで終始している場所であれば、o1にしてしまってもよいかもしれません。(もちろんテスト不足のリスクを許容するならば)

 

o1を使ったこんなテスト作成の流れはどうだろう?

今後実務でも試してみようと思っていますが、こんな流れはどうだろうかと思っています。

  1. o1に仕様を食わせて複数回テスト観点を出す
  2. 全ての結果をマージする (AIを使ってでも手動でも)
  3. 人間がこれまで経験したバグや、気になること、プロジェクトの暗黙知から観点を追加する
  4. テスト観点に優先度をつけ、不要なテスト観点は剪定する
  5. それぞれの観点ごとにパターン出しを行う(人がテスト技法を使っても、o1にやってもらうでも)
  6. テスト観点及び各パターンをo1 に渡してテスト観点ごとにテスト項目化する

 

 

*1:割り勘アプリのテスト観点

*2:割り勘アプリのテスト観点