少し前から、「テスト設計パターン」(Test Design Pattern)というものを考えています。
その定義を説明する前に、なぜこんなことを考え始めたかについての背景から。
テスト設計パターンとは何か
背景
ソフトウェアテストの設計技法は、書籍をはじめとして各所に情報がまとまっており、学習の難易度はそれほど高くないと思います。一方、一通り学んで、さあ使おう!という段階になると、学んだはずの技法がすんなり適用できないことがあります。
その理由は、大きく以下の2つが考えられます。
- 書籍に出てくるような練習問題と違って、現実の仕様とテスト設計技法とは、1:1でキレイに対応しているとは限らない。仕様を解きほぐしていくことで、ある側面は技法A、別の側面は技法Bと対応づいたりする。
- 「よくある仕様に対する、よくあるテストのパターン」、いわゆる「定石」のようなものがあるが、特別なテスト設計技法として扱われていない。各々の経験知で都度、テストケースを作っている。
「テスト設計パターン」という名前で扱いたいのは、この2.です。
「テスト設計パターン」の定義0.1
以下のように、仮に定義しておきます。
テスト設計パターンとは、ソフトウェア開発において現れることの多い仕様に対し、行うべきテスト設計の形をパターン化したものである。
ここでいくつか言い訳をしておきます。
- 「テスト設計パターン」という、いかにも以前からありそうな言葉は、もちろんわたしの発明品ではありません。上述の定義は、完全にわたしのオレオレ定義にすぎません。
- にしさんが過去に言及しています。
- 辰巳さんによると、『Testing Object-Oriented Systems: Models, Patterns, and Tools』(Robert Binder著)に「Test Design Patterns」があるとのことです。わたしはこの内容をちゃんと確認していません。。
- ベリサーブさんでも、これに相当する(だろう)ものを「MBTパターン」と呼んでいるそうです。
- わたしは、「デザインパターン」「パターン言語」についての知識に乏しいです。
仕様スニペットとは何か
「仕様スニペット」の定義0.1
さて、「背景」には「よくある仕様」と書きました。テスト設計パターンとやらを考えるには、それに対応する仕様が必要です。ですが現実の仕様は複雑で、そのテストを考えるには多くの側面に注目する必要があるため議論が発散し、パターン化が難しくなってしまいます。
そこで、現実の仕様を特定の要素だけに絞り込み、テスト設計の議論をしやすくしたものが必要です。これを「仕様スニペット」と呼び、以下のように仮に定義しています。
シンプルかつ抽象化された仕様の断片
- 「シンプル」というのは、議論したい要素にのみ情報を絞り込んでいるという意味です。
- 「抽象化された」というのは、特定のドメイン・開発技術・ツールへの依存性が低いという意味です。 その分コンテキストに乏しくなるのが欠点です。
- 「ソフトウェア仕様の再利用可能なベストプラクティス」ではありません。
たとえば『ソフトウェアテスト技法 練習帳』に出てくる練習問題は、特定のテスト設計技法を適用することに注目できるという意味で、この定義に当てはまると言えます。
「仕様スニペット」という名称はお察しの通り、「コードスニペット」という言葉に倣っています。ただ、specification snippetという単語もわたしの発明品ではなく、たとえばノーコード開発ツールのUnqorkでは、ドキュメント作成の文脈でこの言葉を使っています。
仕様スニペットの目的
- 「仕様に対するテスト設計のパターンを議論すること」を主目的としています。
- ソフトウェア開発において「何かよく見るよね」という仕様をスニペットとして切り出すことで、その側面のみフォーカスしてテストの議論ができるようになることを期待しています。
- 一つのスニペットに情報を盛り込みすぎると、テスト設計の議論が発散するため、上述でいうシンプルさが重要です。
- ドメインやツールへの依存が強いと、汎用的な議論がしづらいので、上述でいう抽象度が必要です。
- 仕様自体の良し悪しも議論できるかもしれませんが、わたしの期待はそこではありません。
仕様スニペットの例
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
更新については仕様で何も言及しなかったのですが、部署変更を意図したテストをされているのが面白かった。上述の通り、仕様スニペット側に反映すべきもの。
- 部門と社員の例だと、多対多を考えるべきで、中間テーブルはあるのだと思います。今回は、1:n固定で考えていたので、例が悪かったかも。
- それぞれのテストケースはもちろん、「観点の決め方」が、まさにほしかったものでした。仕様を見てどういう思考過程が働くか、が大事なので。引用してみます。
- 数字が出てきた時点で境界値分析が必要だと考えました。
- 状態遷移も考えましたが、単純に人数だけなので要らないと考えました。
- 親あたりの子の制約があるので従業員の追加と更新に関してのみデシジョンテーブルを使うと思います。(複数の条件がある場合はデシジョンテーブルを使う)
- 追加と削除と聞くと、CRUDの他の(RとU)も要らないか考えました。
- 中間テーブルの可能性を結構考えましたが、問題文を読んで意図的に削除しました。
おいでさんのコメント
その親と子がどういう使われ方をするかイメージ出来てないのですが、親が営業部、子が関東支部と関西支部みたいな感じでXさんが営業部関東支部、Yさんが営業部関西支部みたいな感じであれば、親に子が紐付かないのが有り得るとして、Zさんが営業部の子の所属無しが有り得るのかは気になりました。
これはおそらく仕様の伝え方が悪くて、わたしは「2つのエンティティが親子関係になる」ことを表現したかったのに対し、おいでさんは「1つのエンティティが入れ子で親子関係を構成する」のを想像したものと思います。ER図で、自分自身に矢印が伸びるやつ。
子が紐付かない親と、子が紐付いてるけど親だけを使うことが出来るか?ということです。
あと、子の削除と紐づけの解除が違う仕様の場合もあるので、そうじゃないかは確認したいです。
この後者の部分は、仕様からまるって抜けていますね。関連付けを削除する=子を削除する だと、「関連付けの変更はできない」ことになってしまうので、確かに仕様として考えづらいです。
やまずんさんの記事
数の最小・最大に注目するところはかいりさんと同じですが、デシジョンテーブルを使っているのが特徴です。
Twitterでも直接会話しましたが、今回の仕様における最小・最大条件は組み合わせを考慮しなくていいので、わたしならデシジョンテーブルは使わないと思います。
こちらのコメント
親を追加できない状態、親を削除できない状態、子を追加できない状態を状態遷移図で表現したかったけど、私では無理でした。
もそうなのですが、「どのような時に、デシジョンテーブルや、状態遷移図を使わないのか」って意外に説明が難しいな?と感じました。これもテスト設計パターンの1つのテーマになるなと考えています。
植月さんのコメント
ロジックの確認にデシジョンテーブル、境界の確認に境界値分析、あと追加と削除の操作シナリオの確認。これは状態遷移図を書いて確認するかも。
植月さんも、デシジョンテーブルと状態遷移図を挙げているので、もうちょい詳しく知りたいところ。
シナリオの観点は、他の方にはあまりなかったかも。わたしも、追加・変更・削除の単機能をつなげたシナリオやりたくなります。
しんすくさんのコメント
親子構造を持つリスト、と考えて、リストのテストのアプローチとして、要素の数の境界値と重複、順序、型、追加削除の機構、親子構造のアプローチとして親の成立、子の成立、仕様上の禁則。とかどうだろ。
重複・順序あたりは他の方にはなかったように思うので、これももうちょい知りたい。
scranbleさんのコメント
関連付けなしで単に親、子の個数の境界値分析 親子の関連付けで子の個数の境界値分析 関連付けが重複してないかどうか (コピーありだと子が溢れるけどスコープ外)
こちらでも「重複」観点が出ていますね。わたしにはピンとこないので、詳しく知りたい。
アシカさんの記事
クラス図で絵にして、さらに例には現れていない「会社」も追加しているのがよかったです。また「部署が0のとき、社員が追加できないことを確認する」も目からウロコでした。出題者なのに。
分析クラス図を作ると、どの境界をテストしたいのかが明確になるような気がしますよね?
かいりさんと同様、アシカさんの記事でも、追加・削除に加えて変更・参照を考慮しています。
- また、同時実行の観点(誰かが削除中のものを、別の誰かが参照、など)も考慮しています。データの整合性やユーザの体験に直接関係するので、大事な観点でうしょね。
テスト設計パターン自体についてのコメント
あきやまさんのコメント
「テスト設計パターン」と「テストアーキテクチャ設計」はお隣さんの距離の技術なのではないだろうか? もしそうならにしさんが考えた「テスト観点を用いて【テストタイプ】を文法構造で整理する方法」が参考になるかもしれないと思いました。 これより細かなテスト設計だとテスト技法になりそう。
これはまだピンと来ていません。テストアーキテクチャ設計と近いですかね・・・?
くっきぃさん&みずのりさんのコメント
みなさんもお気づきの通り、「仕様が曖昧/悪いのでは?」という感触もありまして、やはり仕様とテスト設計に行ったり来たりして、適切なバランス・抽象度に収束させていきたいなと感じます。
以下の、くっきぃさん&みずのりさんのコメントが、その通りだと思う。
昔、社内でコンテキスト特化した感じでテスト設計のパターンかあるだろ?と盛り上がりかけたところで、テスト設計パターンよりも仕様パターンを考えた方が良くない?という話になって消滅した、どちらとも、というのを思い出した。
仕様パターンに典型的なテストがついてくる、ってやつが無難かなー、スペシフィケーションあんどテストデザインパターン セットで情報まとまってると便利そう、だけど種類多すぎて毎回考えたやつがどんだけ流用できるんかねーと思うとこも
で、何がやりたいのか?
ともあれ、このような「仕様スニペットとテスト設計パターン」のペアをいくつかみんなで議論すると、なんかいい感じにフォーマットや粒度が定まってきたり、パターンが整理したりできるようになるのでは?というのが期待です。
スニペット002も考えてみるので、興味ある方、Twitterで反応いただけると嬉しいです。
その場合の留意点は、Twitterにも書きました。
- お題に対し、テスト観点を「もれなく洗い出そう」とやり始めたらキリがない→やる気なくなる になってしまいます。「漏れを指摘されると恥ずかしいから…」とかなっちゃいますよね? なので、「たとえばこんなテスト観点」でいいのです! その「たとえば」をコレクションしたい。
- テスト設計における常套句ですが、「パーフェクトな正解」はないと思ってます。特にこの企画は、仕様がザックリだしコンテキストもないので、なおさらです。逆にだからこそ、本質的で典型的なテスト観点の話ができるかも?とも思ってます。 まあ、大喜利だと思って取り組んでみてもらえれば〜。
情報が集まってきたら、何らか小さいコミュニティを作って議論してみるのもいいと思いますが、まずはTwitterベースでみなさんと議論できればと思っています!
「てか、おまえの答えは?」となるかもしれませんが、記事が長くなりすぎたので、、いったん記事を締めたいと思います。
*1:Twitterで提示したものから、少し表現を変更しています。 #テスト設計パターン を考えるための「仕様スニペット」の例を書き下してみたので、みなさんテスト観点なりテストケースなりを考えてみてください! リプでも引用RTでも大丈夫です。
週明けまでにいくつかでも集まったら、まとめてみますよ~。
…わたしのやりたいこと、伝わるだろうか…?
伝われ…! https://t.co/RJ7JXRwfBe pic.twitter.com/p1RcWAclAl