ソフトウェアの品質を学びまくる

ソフトウェアの品質、ソフトウェアテストなどについて学んだことを記録するブログです。

デジタル庁「テキスト生成 AI 利活用におけるリスクへの対策ガイドブック(α版)」を読んでみた

2024年5月、デジタル庁から『テキスト生成 AI 利活用におけるリスクへの対策ガイドブック(α版)』が公開されました。

www.digital.go.jp

本書自身が「α版」として以下のように注記している通り、生成AIについて特に詳しいわけではもないわたしから見ても、記述に不十分と感じられましたが、「叩き台を作る人はえらい」派の人間なので、このようなものを公開してくれたことに感謝したいです。

実践的なフレームワークやチェックリストによるガイドブックを作成できるまでの知見が蓄積されていないため、留意点の紹介にとどめる。

この記事では、本書の中の特にテスト・品質保証について感じたことを書きたいと思います。本書の概要や構成などについてはすっ飛ばします。

「4 調達実施前時のテキスト生成AI固有の留意点」について

「4 調達実施前時のテキスト生成AI固有の留意点」*1では、

AIの利活用を計画しているシステム管理者が、サービスの期待品質を具体的に理解し、これを適切に盛り込んだ調達要件を作成できるようにすることをスコープとする

としています。2でサービスの効果の考え方、3でコストの話をしており、続く4で品質の話、という流れです。 ただ、導入の文章で「非機能要件」という言葉を使っている一方で、各章ではほぼ回答精度の話にのみフォーカスしており、またその実現方法も「テストケースを充実させる」と、いきなりテストに依拠する形になっています。
最初に定められたスコープでは、「期待品質をどのように定めるか」が語られるかと思ったのですが、「期待品質を下回るリスクを、テストでカバーしよう」という論調になっているように見えます。

本書は

  1. 既存の別ドキュメントを前提としたうえで、リスク軽減の方策についてフォーカスしたものであること
  2. 特にこの4は、生成AIの開発ではなく、事業者の調達を議論していこと

から、あえて記述を薄くしているのかもしれません。

「5 設計・開発時のテキスト生成AI固有の留意点」について

4が「調達」であったのに対し、「5 設計・開発時のテキスト生成AI固有の留意点」は、設計・開発における品質保証です。

本章の目的は、テキスト生成AIを用いたシステムの開発において、生成物の品質を保証し、その評価に関するリスクを軽減するための方法論を提供することである

とあるのですが、5.1では「十分な品質でなかった場合のリスクとその軽減策について述べる」となっています。「品質をどう評価するか」の話のはずが、「品質を評価してダメだったらどうするか」の話になっているように見えるのが気になります。。

QAエンジニア目線では、本書の一番の読みどころは「5.2 テキスト生成AIによる生成物の品質評価・品質保証についてのリスクとその軽減策」です。
この章も構成がややこしい*2ので、5.2.の4)の「この手法には以下のものがある」の部分から読むことをお勧めします。正直、このまとめをまず書いて、この分類に沿って解説していけばいいと思うのですが‥。

このまとめでは、テキスト生成AIを品質保証するための方針と具体策が述べられています。
以下にこれを紹介しますが、分類が一部しっくりこないところがあったので、勝手ながら再構成しています。

方針1: テスト対象のケースを増やす

従来のソフトウェアテストでは、テスト技法の目的の1つは「テストケースを絞り込む」でした。一方機械学習系ソフトウェアにおけるテストでは、「テストケースを増やす」必要性が出てきます。

テストケースの有効な増やし方について、以下の2つを説明しています。

(1) 過去に実際にあったやりとりをそのままテストケースに含める

コールセンター業務のように、過去のやりとりが蓄積されている場合に、その質問をそのままテストデータにするというものです。FAQなどで整理されているようであれば、文字通り頻度高く問われる質問として、テストケースの優先度を上げたりもできそうです。

(2) 作成したテストケースの入力文の言い換え処理をテキスト系生成AIに実施させる

本書では具体的なテスト技法への言及はないのですが、メタモルフィックテスティングの発想に近いと思います。1つのテストケースから多数のテストケースを派生させることで、テストオラクル問題を軽減できます。

メタモルフィックテスティングだと入力側も出力側も変化の対象になりますが、このケースは「入力に多少の変化を加えても、出力が変わらないこと」を期待しているので、限定的な使い方と言えるかもしれません。

「テストケースを増やす」話や、メタモルフィックテスティングについては、こちらの記事でも言及しています。 www.kzsuzuki.com

方針2: 大量のテストケースを評価する

方針1でがんばってテストケースを増やしたとして、結果の妥当性はどう評価すればいいでしょうか。物量と戦うには腕力ということで、評価を機械に肩代わりさせるための策が提案されています。

(1) 知識の有無を選択問題によって評価する

知識が正しく反映されているかを確認する用途であれば、自由回答させるのではなく選択式にすることで、回答の妥当性の確認を機械が代替しやすいです。

(2) 機械的な品質評価手法を導入する

自分の理解に自信がありませんが、「期待値」としての文章を事前に用意したうえで、実際の回答の文章を比較し、その類似度が一定以上であれば正解であると見なす、という考えかと思います。既存の技術も流用できます。

(3) 人間の評価者が行うテストケースを絞り込む

上のような具体策をとったうえで、特定の条件を満たすもののみ人間が評価を行うというものです。

方針3: 主観をできるだけ排除する

生成AIにはバイアスが入り込むリスクがあると言われますが、それは評価側の人間も同様。主観をできるだけ排除するために、以下の2つの策が提案されています。ちょっとレビューと似ていますね。

(1) 評価観点や基準を明確にする
(2) 複数人により独立に実施する

方針4: 生成物のばらつきに対処する

機械学習の話題が盛んになったころから、出力が非決定論的であることは課題の1つとされていました。が、生成AIにおいてはその非決定性がむしろ利点ともなりえます。そして、テストにおける悪夢ともいえます。
提示される方策は以下。

(1) ばらつきに関するパラメータを調整する

テスト以前に「そもそも、ばらつかせない」という方針ですね。GPTでいうところの temperature にあたるパラメターでしょう。temperature は、「値が大きいとランダム性が大きく、小さければより決定論的になる」としています

(2) 同じテストを繰り返し行う

個人的には、ここに一番興味を持っています。
見た目は同じ条件・同じ入力であっても、原則として出力は同一でない。このような特徴をもったシステムに対して複数回のテストを行って妥当性を判断するというのは、単純なのになぜか面白さを感じています。
次回は、ここにフォーカスした記事を書きたいなと思っています。

おわりに

テキスト生成AIを利用したシステムの開発とそれに伴う調達において、どのようなリスク・留意点があるのかについて、現時点の知識でできるだけ網羅的に記載しようという試みに感謝です。特に、品質評価における具体策は参考になるものでした。

Generated By Dalle

*1:「前時」は誤記なのか、役所用語なのか‥?

*2:ドキュメント全体の構造化と見栄えにもう少し工夫があると、読みやすくなるのになあという思いがあります。
たとえば以下のような箇所は、文章の階層構造が把握できず、読むのがとても苦しかったです。。なおここでは、2) があって、その下に ア があり、その下に 軽減策 があって、その下に (1) があるという構造です。インデント‥。

本ガイドブックのスクリーンショット

仕様スニペット003「ログインパスワードの再設定」の #テスト設計パターン を考えてみる

5月19日に、3つ目の仕様スニペット・「003: ログインパスワードの再設定」を公開しました。
2つ目まではわたし自身が作っていたのですが、3つめはかいりさんがネタを提供くださいました!

docs.google.com

「テスト設計パターン」「仕様スニペット」って何?という方は、こちらの記事を先にご覧くださいね。

www.kzsuzuki.com

仕様スニペット003: 「ログインパスワードの再設定」

以下の仕様に示されるアカウントロックについて、テスト観点を考えてください。

  1. メールアドレスを入力すると、そのメールアドレスに再発行URLが送信される。
  2. 再発行URLにアクセスすると、パスワードを再設定することができる。
  3. URLは、発行後30分間有効である。

002と比べても、かなりシンプルですよね。仕様スニペットがシンプルであるほど、テスト観点がソリッドになっていくと思うのですが、その分コンテキストが失われて議論しづらいというトレードオフ。。

回答の例

鈴木の場合

わたしの頭に浮かんのは、こんな感じです。
頭に浮かんだ順ではなく、ちょっと整理しています。

ハッピーパス
  • 実在する正当なユーザによるハッピーパス
    • 再設定したパスワードでログインできるか
  • 再設定は複数回行えるか
メールアドレスの有効・無効
  • 登録されていないメールアドレスに対しる再設定要求
    • 「登録されていないメールアドレスである」情報を開示するかどうかのポリシー確認
  • RFCには従っているけど通常は使われない記号の場合も対応できるか
設定パスワードの有効・無効
  • パスワードのルールはどうなっているか
    • 初期設定時と変更時でルールが違うとバグの予感がする
    • 変更「前」と同じパスワードは設定できるかのポリシーも確認したい
URLの有効・無効
  • URLが、30分以内は有効で、30分以降は無効になるか
    • 厳密な境界値テストはできないけれど、そこまで厳密さはいらないと想定
  • URL期限切れ前に再度、再設定要求した場合の挙動
    • 先にもらった方のURLは無効化されるのではないか
      • 無効化される前に開いておいた画面でパスワード変更できるのか?
セキュリティ
  • 故意に他人のメアドの再設定しようとする攻撃をされても、メアドの所有者に害はないか

みわさんの場合

個々の観点も良いのですが、「そのための行動」として過去チケットを検索するというのがとても良いですね。
バグチケットを蓄積してきた組織は、生成AIの普及に伴って強力な”チカラ”を手にするんじゃないかと思います。

以下が、過去事例として出たものとのこと。これを逆引きすればテスト観点にもなりますね。

・パスワードを自動生成する機能を利用すると画面がフリーズする
・パスワード再発行できない
・パスワード再発行してもログインできない
・パスワード再発行が利用できない
・パスワードリセットなど一部のメール送信に失敗していた
・自動ログインせず、ログイン画面になる
・再設定後、ログイン画面でパスワードを入れても認証エラーになる
・特定のブラウザでパスワードの再設定ができない
・言語設定が「日本語」だとパスワードが設定できない
・パスワード再発行のメール配信に大幅な遅延が発生した
・必須ではない項目をパスワード再発行の確認手続き項目に使用していた

この5つ目「メール送信に失敗」で思い出したのですが、送信ドメイン認証をパスしないメールを拒否している場合もあるよなあと。メールの不達ケースは重要なポイントですね。

Cazunari Murahoさんの場合

有効期限切れの URL にアクセスした時に、ユーザ向けの画面が表示されるか

これは基本パターンとして必須ですね。

やまずんさんの場合

・基本的に仕様コピペで確認しますが、再発行したあとのアカウントでのログインとか、再発行を2回した場合に1回目のURLはどうなるかとかは気になりそうです。
・「再設定後にそのURLが無効になるかどうか」は意外とまだないのか
・URLが無効になるきっかけが期限切れ以外にあるのか?(この場合設定した場合は?)
・再発行URL改ざんしたら別の発行URLに飛ぶと草

この2点目でハッとしたのですが、「Aの場合にBとなる」という仕様を見たら、「Bとなるケースはそれ以外にないのか」を考えるというのは良いテスター仕草という感じがしますね。002のアカウントロックでも、似た話がありました。

今回「払い出されたURLが無効になるのはどんなケース?」と考えると、以下のケースがありそうです。

  1. 30分の期限が切れた
  2. パスワードの再設定に一度利用された(仕様確認)
  3. 別のURLが新たに発行された(仕様確認)

𝓜𝓪𝓼𝓪𝔂𝓾𝓴𝓲 𝓣𝓪𝓬𝓱𝓲𝓫𝓪𝓷𝓪さんの場合

絶対にやれないと思いますが、入力されたパスワードが過去に漏洩したパスワードかをダークウェブ検索サービスで検索し警告を促すシステムかどうか。

これはまったくの想定外でしたね。パスワード設定機能において、こういうのが合ったら面白そうです。

おいでさんの場合

前のパスワードが使えなくなることの確認もしないといけないと思ってる

シンプルですが、まずハッピーパスの確認観点として必要なものですね。

rinoさんの場合

非機能(≒仕様スニペット外)
・複数リクエストで有効なURL
・メールアドレスが存在しなかったときの挙動(公開とイントラで出方変わるはず)
・再発行が要求できる時間間隔

他機能への影響
・ログイン中にパスワード再設定したときのログイン状態
・発行~再設定間で現行パスワードでのログイン

「他機能への影響」が、わたしの思いついた観点では漏れていました。次の画面遷移時の強制ログアウトが正しい気がしますが、仕様確認が必要ですね。

おわりに

仕様をここまでシンプルなものにしても、けっこう観点が出てくるものですねー。一方シンプルなだけに観点の方向性が発散せず、よい例題だなーと思いました。

実はかいりさんはもう1つネタをくれているので、近々004を公開したいと思います!

仕様スニペット002「アカウントロック」の #テスト設計パターン を考えてみる

5月3日に、2つ目の仕様スニペット・「002: アカウントロック」を公開しました。

docs.google.com

「テスト設計パターン」「仕様スニペット」って何?という方は、こちらの記事を先にご覧くださいね。 www.kzsuzuki.com

仕様スニペット002: 「アカウントロック」

以下の仕様に示されるアカウントロックについて、テスト観点を考えてください。

  1. ユーザはログインの際に、アカウント名とパスワードが求められます。
    ※アカウント名・パスワードの文字列長・文字種などについては、議論の対象外とする。
  2. アカウント名とパスワードの組み合わせが正しい場合、ログインが成功します。
  3. アカウント名とパスワードの組み合わせが正しくない場合、ログインが失敗します。
  4. あるユーザ名に対し、ログインが3回連続で失敗した場合、アカウントがロックされます。
    ※アカウントロックの解除については、議論の対象外とする。
  5. ログインが成功した際に、ログイン失敗回数はゼロにリセットされます。

001が、わたしの意図する仕様スニペットの位置づけに対して少し複雑だったように感じて、今回はかなりシンプルなものです。
今回も、何人かの方が検討をしてくれました。それぞれを読んで思ったのですが・・・、

優秀なQAの人たちの習慣として、仕様を提示されたら、

  1. 内部の作りがどうなっているかを想定し、それを開発者に確認しようとする
  2. 仕様自体も間違っている、網羅性が低い、考え漏れがある前提で、仕様のより良い姿を見つけようとする

んですよね。
もちろんこれは、いいことだとわたしは思います。ですがそのことが、「テスト設計パターン」の成立を難しくさせるなとも感じました。なぜなら、「シンプルで完全な仕様」というものは、提示し得ないからです。

それはさておき、先に進みましょう。

回答の例

かいりさんの記事

前回に続いて記事化してくださいました。

note.com

どの部分も頷けるものばかりなのですが、特にいいなあと思ったのが、「ロックに至る理由が、3回連続失敗とは限らない」と判断している点です。ユーザのミス以外にもロックさせる契機はありうると考えて、「連続失敗回数」と「ロックされている/いない」の情報は分離されていると想定しているんですね。仕様を鵜呑みにしているだけだと、そこまで考えられないかもしれません。
で、失敗回数・ロック有無の2つの情報と、ユーザ名とパスワードの組み合わせが正しいかという3点をもって、デシジョンテーブルを作成しています。

デシジョンテーブルを書かれる過程を読んでふと思っていたのですが、わたしとは思考の順番が逆かもな?と思いました。
わたしの場合、条件整理→テーブル じゃなくて、テーブルを書きながら条件整理をしているようなところがあります。

おいでさんのコメント

パスワードを忘れた場合のパスワードリセットの仕様を考慮するかしないかが悩みどころかもしれないですね。

パスワードリセット機能や、別の理由(サブスク料金未払いなど)でのアカウントロックについては今回は対象外としますが、これらもこれらで面白そうですよね。

アカウント名hide_ramen_sanのパスワードがpasswordだったとして、hide_ramen_sanでパスワード3回間違えたらロックかかるけど、パスワードpasswordに対してアカウント名を3回間違えても(hide-ramen-sanとかhideramensanとか入れても)ロックかからないという仕様になると思うんですよね。

「パスワード側を固定した不正ログインアタック」みたいなのはかいりさんも言及されていましたが、これも対象外で・・・。

𝓜𝓪𝓼𝓪𝔂𝓾𝓴𝓲 𝓣𝓪𝓬𝓱𝓲𝓫𝓪𝓷𝓪さんのコメント

一般ユーザーか管理者権限ユーザーかによって、ロック条件が変わりそうですが、今回のは一般ユーザーのものとして、管理者権限ユーザーは、別問題でよいでしょうか。

わたしは一般ユーザしか考えていませんでしたが、確かにユーザ種別によって仕様が違うケースもありそうです。

miwaさんの記事

miwa719.hatenablog.com

わたしの設問に対するものではないのですが、「ログイン機能」を与えられたときにmiwaさんが考えるテスト観点についての記事です。

たった3行の文章からここまで広げられるのにやっぱり脱帽ですし、仕様を所与のものとせず、「なにがうれしいの?」「なんのために」「ほんとうに」「なぜ」と問うているのもさすがですよね。

おわりに

与えられた仕様から、みなさんが何を考え、どう振る舞い、どんなテストケースを設計していくかを知るのは、自分自身とてもいい勉強になります。「テスト設計パターン」などと仰々しいものでなくても、「こんな仕様にはどんなテストする?」とワイワイ話すだけでもいい気がしてきました。

が、もうしばらくやっていきます。
第3、第4の仕様スニペットは、かいりさんが考えてくれましたので、近日Twitterにて公開します!

自然言語からデシジョンテーブルを生成する、GIHOZ AIを触ってみた

ベリサーブ社が公開しているソフトウェアテスト技法サービス「GIHOZ」で、ベータ機能として「GIHOZ AI」が公開されました。 www.veriserve.co.jp

4月時点で利用できるのは、「仕様書などの文字情報からデシジョンテーブルを自動生成する」というものです。これまでは人間がモデルを描いていましたが、その部分をAIに任せられるということになるでしょう。

タスク 従来のGIHOZ GIHOZ AI
仕様の作成 人間 人間
モデルの作成 人間 GIHOZ
テストケースの作成 GIHOZ GIHOZ

これはMBT(Model Based Testing)の夢が広がりますね~。

さっそく触ってみる

さっそく試してみましょう!

GIHOZ AIのUI

こんな感じのUIで、レスポンスは概ね1分以内。30~40秒程度でしょうか。デシジョンテーブルをの生成は、1日あたり5回まで試すことができます。

それでは、以下の順に試していきたいと思います。

  1. シンプルな仕様
  2. 少しひねった仕様
  3. 整理されていない仕様
  4. 論理関係がややこしい仕様
  5. ハルシネーションを起こしやすそうな仕様

先に結果を書いておくと、以下のようになります。

  • 1、2、3は問題なく生成できる
  • 4のように、仕様の記述がひどいと、結果も間違いやすくなる
  • 5のように、特殊な仕様を入れると、動作が怪しいことがある

自分の作ったGPTsが一瞬でプロンプトをさらけだしてしまったことがあるので、プロンプトインジェクションにも興味があります。が、これはセキュリティ攻撃みたいなものなので、当然他社のサービスには試せません。

シンプルな仕様

『ソフトウェアテスト技法ドリル』のデシジョンテーブルの章の問題で試してみましょう。

あるECサイトでは、「商品カテゴリーが書籍である」 かつ 「価格が1,500円以上である」 かつ 「配送先が離島でない」 場合に「送料が無料」となる。

シンプルな仕様

さくっと正解です。いやこれ、当たり前のように出力されますけど、素晴らしいことだと思いますよ。従来は、このテーブルを人間がピコピコ作っているのですから。
「未満1500円」という文言は気になりますが、もう一度生成させてみると、「1500円未満」となりました。

少しひねった仕様

上の例より若干複雑にしたものです。

仕様1: 書籍 かつ 1,500円以上 かつ 離島以外 なら、配送料無料
仕様2: 書籍 かつ 1,500円以上 かつ 離島 なら、配送料300円
仕様3: 書籍 かつ 1,500円以上でない なら、配送料400円
仕様4: 書籍でない かつ 離島以外 なら、配送料500円
仕様5: 書籍でない かつ 離島 なら、配送料1,000円

少しひねった仕様

こちらも正しく生成できています!

整理されていない仕様

上の2つの例は、仕様の記述がかなり整理されており、言ってみれば文章そのものが「モデル」相当になっていると言えます。まあ仕様書であれば当然かもしれませんが、とにかく生成AIには扱いやすいものと言えるでしょう。

ということで、もうちょっと整理されていない感じで書き直してみましょう。

書籍で1500円以上なら配送料は無料だ。ただし離島の場合は300円かかる。
書籍でない場合は配送料は500円。離島なら1000円にする。
書籍であっても、1500円未満なら400円の配送料を課す。

日本語としてそこまでひどくはないのですが、「ただし」で後出しジャンケンしたり、出てくる金額が「購入金額」なのか「配送料」なのかが曖昧だったり、仕様の記述としてはイマイチですね。

整理されていない仕様

素晴らしい、正解です!
この程度の「いまいちな記述」なら、しっかり理解してくれます。わたしなら、こういう仕様記述は間違いなくナオシを入れます。

論理関係がややこしい仕様

論理関係の表現を無駄にややこしくしてみましょう。

(書籍でない かつ 離島でない)ではない場合は配送料100円。
書籍でない かつ 離島以外の場合は配送料200円。

これはもう嫌がらせですね。
1行目の仕様はド・モルガンの法則から、「書籍である または 離島である、ならば配送料100円」。2行目の仕様はその補集合です。

論理関係がややこしい仕様

ここまでヒドイ記述だと、さすがに誤りが発生してしまいました。
おそらく1行目の「ではない」を「離島でない」にのみ作用させているのではないかと思います。そのため、この2行でカバーできないケースを「無料」と補完したのでしょう。入力文章の方が悪いですね。。

このように、「そもそも仕様の記述が整理されていない」場合は、先に別の生成AIに食わせて整理した方がいいかもしれません。ChatGPTでは以下のように答えてくれました。

指定された仕様をもとに、論理関係を整理して分かりやすく書き直します。

  1. 「(書籍でない かつ 離島でない)ではない場合は配送料100円」という条件は、論理演算において「または」を用いて書き換えることができます。つまり、「書籍である または 離島である」場合、配送料は100円です。
  2. 「書籍でない かつ 離島以外の場合は配送料200円」という条件は、書籍ではなく、かつ、離島でもない場合に配送料が200円となります。

整理すると以下のようになります:

  • 書籍である場合、または、配送先が離島である場合、配送料は100円です。
  • 書籍ではなく、配送先が離島でもない場合、配送料は200円です。

ChatGPTに直してもらった後

正しく生成されました。

ハルシネーションを起こしやすそうな仕様

どういう仕様ならハルシネーションを起こすかを考えてみましょう。

よく引き合いに出される例ですが、「日本で一番高い山は」と文字列が続くと、その次には「富士山」という単語が来る確率がもっとも高いので、LLMはそれを返している(というのが今のわたしの理解です、違ったらスミマセン)。
逆に、「生成AIが”次の単語”として想定する流れを裏切るもの」があれば、間違いを引き起こすのでは?と考えました。

FizzBuzzっぽいけど違う

プログラミングの例として Hello World! の次に多そうな、FizzBuzz問題をちょっと変更して聞いてみましょう。

入力された整数に対し、その整数が3の倍数なら「Fizz」、6の倍数*1なら「Buzz」、両方の倍数なら「Fizz Buzz」、いずれでもなければ元の整数を返す。

FizzBuzzっぽいけど違う

全然だまされませんね。

うるう年っぽいけど違う

偽うるう年判定でも試してみましょう。

グレゴリオ暦法では、うるう年を次のように決めています。
(1)西暦年号が4で割り切れる年をうるう年とする。
(2)(1)の例外として、西暦年号が100で割り切れて200で割り切れない*2年は平年とする。

うるう年っぽいけど違う

だいぶおかしなものが出てしまいました。
これをハルシネーションと呼ぶべきかはわかりませんが、本来は全8パターン(23)個あるべきものが3パターンになっています。ありえないケースを自動的に圧縮した可能性も考えましたが、テストケース#2は「100で割り切れる かつ 4で割り切れない」ものとなっており、そういうわけではなさそうです。条件がすべてNになるケースも漏れています。

もう一度生成してみましょう。

うるう年っぽけど違う2

悪化してしまいました・・・。

うるう年

現実のうるう年の定義と異なるせいかもしれません。正しい仕様に戻してみましょう。

グレゴリオ暦法では、うるう年を次のように決めています。
(1)西暦年号が4で割り切れる年をうるう年とする。
(2)(1)の例外として、西暦年号が100で割り切れて400で割り切れない年は平年とする。

うるう年

今度は適切ですね(F・H・I・Jのチェックは手動で外しています)。

「うるう年っぽいけど違う」で正しくテーブルを生成できなかった理由が、「生成AIが”次の単語”として想定する流れを裏切るもの」だったせいかどうかはわかりません。ただいずれにせよ、生成AIの回答は正確さが保証されたものではないことに、あらためて注意です。

これは当然ながら、GIHOZ AIの「利用上の注意」にも記載されています。

GIHOZ AIは現在ベータ版であり、本機能で出力される内容には不正確な情報が含まれる可能性があります。本機能を利用するときは必ず結果を確認し、ユーザ自身の責任において利用の可否を判断してください。また、ユーザが入力した内容によっては結果を出力できずエラーになる場合があります。

まあ後半の方の例は、「生成AIの限界」云々以前に「仕様が終わってるよね」って話だと思います。。

まとめ

触ってみて、「まともな自然言語で書かれた仕様であれば、おおむね妥当なデシジョンテーブルを作ってくれそうだ」という感触を得ました。
素晴らしいですね。テスト設計技法のツールという分野を開拓していくベリサーブさんのチャレンジに感謝です。

一方で当然ながら、Garbage In, Garbage Outの原則にも注意はいるだろうと感じます。
生成AIは自然言語で対話できるうえに、ある程度妥当なコンテキストも補ってくれますが、やはり「文章を論理的かつ簡潔に記述する力」が、人間側にまだまだ必要だと感じました。これによって、生成AIを利用したプロダクトの力を引き出せるのだろうと思います。

Generated By Dalle

*1:本来は5の倍数

*2:本来は400で割り切れない

#テスト設計パターン を考える会 をTwitterベースでやってみた

少し前から、「テスト設計パターン」(Test Design Pattern)というものを考えています。
その定義を説明する前に、なぜこんなことを考え始めたかについての背景から。

テスト設計パターンとは何か

背景

ソフトウェアテストの設計技法は、書籍をはじめとして各所に情報がまとまっており、学習の難易度はそれほど高くないと思います。一方、一通り学んで、さあ使おう!という段階になると、学んだはずの技法がすんなり適用できないことがあります。
その理由は、大きく以下の2つが考えられます。

  1. 書籍に出てくるような練習問題と違って、現実の仕様とテスト設計技法とは、1:1でキレイに対応しているとは限らない。仕様を解きほぐしていくことで、ある側面は技法A、別の側面は技法Bと対応づいたりする。
  2. 「よくある仕様に対する、よくあるテストのパターン」、いわゆる「定石」のようなものがあるが、特別なテスト設計技法として扱われていない。各々の経験知で都度、テストケースを作っている。

「テスト設計パターン」という名前で扱いたいのは、この2.です。

「テスト設計パターン」の定義0.1

以下のように、仮に定義しておきます。

テスト設計パターンとは、ソフトウェア開発において現れることの多い仕様に対し、行うべきテスト設計の形をパターン化したものである。

ここでいくつか言い訳をしておきます。

  • 「テスト設計パターン」という、いかにも以前からありそうな言葉は、もちろんわたしの発明品ではありません。上述の定義は、完全にわたしのオレオレ定義にすぎません。
    • にしさんが過去に言及しています。
    • 辰巳さんによると、『Testing Object-Oriented Systems: Models, Patterns, and Tools』(Robert Binder著)に「Test Design Patterns」があるとのことです。わたしはこの内容をちゃんと確認していません。。
    • ベリサーブさんでも、これに相当する(だろう)ものを「MBTパターン」と呼んでいるそうです。
  • わたしは、「デザインパターン」「パターン言語」についての知識に乏しいです。

仕様スニペットとは何か

「仕様スニペット」の定義0.1

さて、「背景」には「よくある仕様」と書きました。テスト設計パターンとやらを考えるには、それに対応する仕様が必要です。ですが現実の仕様は複雑で、そのテストを考えるには多くの側面に注目する必要があるため議論が発散し、パターン化が難しくなってしまいます。
そこで、現実の仕様を特定の要素だけに絞り込み、テスト設計の議論をしやすくしたものが必要です。これを「仕様スニペット」と呼び、以下のように仮に定義しています。

シンプルかつ抽象化された仕様の断片

  • 「シンプル」というのは、議論したい要素にのみ情報を絞り込んでいるという意味です。
  • 「抽象化された」というのは、特定のドメイン・開発技術・ツールへの依存性が低いという意味です。 その分コンテキストに乏しくなるのが欠点です。
  • 「ソフトウェア仕様の再利用可能なベストプラクティス」ではありません

たとえば『ソフトウェアテスト技法 練習帳』に出てくる練習問題は、特定のテスト設計技法を適用することに注目できるという意味で、この定義に当てはまると言えます。

「仕様スニペット」という名称はお察しの通り、「コードスニペット」という言葉に倣っています。ただ、specification snippetという単語もわたしの発明品ではなく、たとえばノーコード開発ツールのUnqorkでは、ドキュメント作成の文脈でこの言葉を使っています

仕様スニペットの目的

  1. 「仕様に対するテスト設計のパターンを議論すること」を主目的としています。
    • ソフトウェア開発において「何かよく見るよね」という仕様をスニペットとして切り出すことで、その側面のみフォーカスしてテストの議論ができるようになることを期待しています。
    • 一つのスニペットに情報を盛り込みすぎると、テスト設計の議論が発散するため、上述でいうシンプルさが重要です。
    • ドメインやツールへの依存が強いと、汎用的な議論がしづらいので、上述でいう抽象度が必要です。
  2. 仕様自体の良し悪しも議論できるかもしれませんが、わたしの期待はそこではありません。

仕様スニペットの例

1つ目の例として、以下のようなものを考えてみました*1
これはお試しに作ったもので、上で提示した定義にふわしいものか、フォーマットとして適切かはまったく煮詰まっていません。

仕様スニペット001: 「1:n構造のエンティティ削除」

以下の仕様に従う2つのエンティティの追加・削除についてのテスト観点を考えてください。

# 仕様
1 2種類のエンティティAとBには親子関係があり、Aが親、Bが子となります。 Aが部署、Bが社員、といった関係です。
2 親Aの数は、全体で0個以上64個以下です。この範囲で追加・削除ができます。 部署は最小0個、最大64まで。
3 子Bの数は、全体で0個以上128個以下です。この範囲で追加・削除ができます。 社員は最小0、最大128まで。
4 親Aは、0個以上16個以下の子Bを持つことができます。 部署には複数人の社員が所属することができます。1人の場合もあり、また0人の場合もあります。
5 子Bは、必ず1個の親Aを持ちます。 社員はただ1つの部署に所属することができます。兼務はありません。
6 子Bは、いつでも削除することができます。 社員は常に削除可能です。
7 関連づく子Bが1つ以上存在する限り、親Aを削除することはできません。 社員が残っている部署を削除することはできません。

この時点でスニペットのタイトル(削除)と問題(追加と削除)がブレていることがわかっていただけると思います。。
最初は、「削除」だけを考えておりまして、数の最小最大の仕様などもなかったのですが、「いくらシンプルにといっても、これだけでは・・」と付け足しているうちに、仕様が膨らんでしまっています。

一方で、この問題に取り組んでくださった方は、「変更」(たとえば社員単体の情報の変更や、社員の部署変更など)を考慮されており、このスニペットがどうも中途半端であることがわかります。
おそらく、仕様スニペットとテスト設計パターンは、交互に行き来しながらバランスを探っていくべきなのでしょう。

回答の例

Twitterで、たくさんの方が反応してくれました。見逃しあったらゴメンナサイ。
みなさんの記事やコメントに対して、感想を書いていきます。

かいりさんの記事

note.com

  • 仕様から内部構造を想定したうえで「要確認」としているのが好きです。特にここでいう「削除」が論理削除か物理削除なのかは、かいりさんご自身の記事にもあるように複数の実現方法があるので、重要ですよね。 note.com

  • 更新については仕様で何も言及しなかったのですが、部署変更を意図したテストをされているのが面白かった。上述の通り、仕様スニペット側に反映すべきもの。

  • 部門と社員の例だと、多対多を考えるべきで、中間テーブルはあるのだと思います。今回は、1:n固定で考えていたので、例が悪かったかも。
  • それぞれのテストケースはもちろん、「観点の決め方」が、まさにほしかったものでした。仕様を見てどういう思考過程が働くか、が大事なので。引用してみます。
    • 数字が出てきた時点で境界値分析が必要だと考えました。
    • 状態遷移も考えましたが、単純に人数だけなので要らないと考えました。
    • 親あたりの子の制約があるので従業員の追加と更新に関してのみデシジョンテーブルを使うと思います。(複数の条件がある場合はデシジョンテーブルを使う)
    • 追加と削除と聞くと、CRUDの他の(RとU)も要らないか考えました。
    • 中間テーブルの可能性を結構考えましたが、問題文を読んで意図的に削除しました。

おいでさんのコメント

その親と子がどういう使われ方をするかイメージ出来てないのですが、親が営業部、子が関東支部と関西支部みたいな感じでXさんが営業部関東支部、Yさんが営業部関西支部みたいな感じであれば、親に子が紐付かないのが有り得るとして、Zさんが営業部の子の所属無しが有り得るのかは気になりました。

これはおそらく仕様の伝え方が悪くて、わたしは「2つのエンティティが親子関係になる」ことを表現したかったのに対し、おいでさんは「1つのエンティティが入れ子で親子関係を構成する」のを想像したものと思います。ER図で、自分自身に矢印が伸びるやつ。

子が紐付かない親と、子が紐付いてるけど親だけを使うことが出来るか?ということです。
あと、子の削除と紐づけの解除が違う仕様の場合もあるので、そうじゃないかは確認したいです。

この後者の部分は、仕様からまるって抜けていますね。関連付けを削除する=子を削除する だと、「関連付けの変更はできない」ことになってしまうので、確かに仕様として考えづらいです。

やまずんさんの記事

uskymstp.hatenablog.com

数の最小・最大に注目するところはかいりさんと同じですが、デシジョンテーブルを使っているのが特徴です。
Twitterでも直接会話しましたが、今回の仕様における最小・最大条件は組み合わせを考慮しなくていいので、わたしならデシジョンテーブルは使わないと思います。

こちらのコメント

親を追加できない状態、親を削除できない状態、子を追加できない状態を状態遷移図で表現したかったけど、私では無理でした。

もそうなのですが、「どのような時に、デシジョンテーブルや、状態遷移図を使わないのか」って意外に説明が難しいな?と感じました。これもテスト設計パターンの1つのテーマになるなと考えています。

植月さんのコメント

ロジックの確認にデシジョンテーブル、境界の確認に境界値分析、あと追加と削除の操作シナリオの確認。これは状態遷移図を書いて確認するかも。

植月さんも、デシジョンテーブルと状態遷移図を挙げているので、もうちょい詳しく知りたいところ。
シナリオの観点は、他の方にはあまりなかったかも。わたしも、追加・変更・削除の単機能をつなげたシナリオやりたくなります。

しんすくさんのコメント

親子構造を持つリスト、と考えて、リストのテストのアプローチとして、要素の数の境界値と重複、順序、型、追加削除の機構、親子構造のアプローチとして親の成立、子の成立、仕様上の禁則。とかどうだろ。

重複・順序あたりは他の方にはなかったように思うので、これももうちょい知りたい。

scranbleさんのコメント

関連付けなしで単に親、子の個数の境界値分析 親子の関連付けで子の個数の境界値分析 関連付けが重複してないかどうか (コピーありだと子が溢れるけどスコープ外)

こちらでも「重複」観点が出ていますね。わたしにはピンとこないので、詳しく知りたい。

アシカさんの記事

tyngw.hatenablog.com

  • クラス図で絵にして、さらに例には現れていない「会社」も追加しているのがよかったです。また「部署が0のとき、社員が追加できないことを確認する」も目からウロコでした。出題者なのに。

    分析クラス図を作ると、どの境界をテストしたいのかが明確になるような気がしますよね?

  • かいりさんと同様、アシカさんの記事でも、追加・削除に加えて変更・参照を考慮しています。

  • また、同時実行の観点(誰かが削除中のものを、別の誰かが参照、など)も考慮しています。データの整合性やユーザの体験に直接関係するので、大事な観点でうしょね。

テスト設計パターン自体についてのコメント

あきやまさんのコメント

「テスト設計パターン」と「テストアーキテクチャ設計」はお隣さんの距離の技術なのではないだろうか? もしそうならにしさんが考えた「テスト観点を用いて【テストタイプ】を文法構造で整理する方法」が参考になるかもしれないと思いました。 これより細かなテスト設計だとテスト技法になりそう。

これはまだピンと来ていません。テストアーキテクチャ設計と近いですかね・・・?

くっきぃさん&みずのりさんのコメント

みなさんもお気づきの通り、「仕様が曖昧/悪いのでは?」という感触もありまして、やはり仕様とテスト設計に行ったり来たりして、適切なバランス・抽象度に収束させていきたいなと感じます。
以下の、くっきぃさん&みずのりさんのコメントが、その通りだと思う。

昔、社内でコンテキスト特化した感じでテスト設計のパターンかあるだろ?と盛り上がりかけたところで、テスト設計パターンよりも仕様パターンを考えた方が良くない?という話になって消滅した、どちらとも、というのを思い出した。

 

仕様パターンに典型的なテストがついてくる、ってやつが無難かなー、スペシフィケーションあんどテストデザインパターン セットで情報まとまってると便利そう、だけど種類多すぎて毎回考えたやつがどんだけ流用できるんかねーと思うとこも

で、何がやりたいのか?

ともあれ、このような「仕様スニペットとテスト設計パターン」のペアをいくつかみんなで議論すると、なんかいい感じにフォーマットや粒度が定まってきたり、パターンが整理したりできるようになるのでは?というのが期待です。
スニペット002も考えてみるので、興味ある方、Twitterで反応いただけると嬉しいです。

その場合の留意点は、Twitterにも書きました。

  • お題に対し、テスト観点を「もれなく洗い出そう」とやり始めたらキリがない→やる気なくなる になってしまいます。「漏れを指摘されると恥ずかしいから…」とかなっちゃいますよね? なので、「たとえばこんなテスト観点」でいいのです! その「たとえば」をコレクションしたい。
  • テスト設計における常套句ですが、「パーフェクトな正解」はないと思ってます。特にこの企画は、仕様がザックリだしコンテキストもないので、なおさらです。逆にだからこそ、本質的で典型的なテスト観点の話ができるかも?とも思ってます。 まあ、大喜利だと思って取り組んでみてもらえれば〜。

情報が集まってきたら、何らか小さいコミュニティを作って議論してみるのもいいと思いますが、まずはTwitterベースでみなさんと議論できればと思っています!
「てか、おまえの答えは?」となるかもしれませんが、記事が長くなりすぎたので、、いったん記事を締めたいと思います。

Generated By Dalle

*1:Twitterで提示したものから、少し表現を変更しています。