このエントリは ソフトウェアテストあどべんとかれんだー 2014 の 6 日目のエントリです。
前日は Yuji Yamamoto さんの『より「普通に」書くためのTest Doubleライブラリ「crispy」 #ruby #SWTestAdvent』でした。
Ruby Advent Calendar と同時寄稿というのはおもしろい試みですねー!僕も Rubyist の端くれなので大変参考になりました。
さて、僕は具体的なテスト実装の話ではなくもうちょっとプロセス論寄りの話をします。もっと率直に言うとポエムに近いです。
自己紹介
すえなみと申します。漢字で書くと末並です。「末波」とよく間違われますが「末並」です。
とても希少な名字なので勉強会等で「すえなみ」と名乗ってる人間がいたら間違いなく僕のことだと思ってください。 オンラインでは a_suenami とか a.suenami とかで活動してます。
Twitter: https://twitter.com/a_suenami
Facebook: https://www.facebook.com/a.suenami
所属は渋谷にあるファクトリアルという会社で、受託開発のお仕事をしています。Ruby、PHPあたりがメインの開発言語です。 よろしくお願いします。
前書き(謝辞)
このエントリはきょん @kyon_mm さんが JaSST’14 東北*1で発表した「テストの使い方」およびそれについて直接お話しさせてもらった内容をもとにして、僕の経験や普段考えていることを組み合わせて僕なりにまとめた内容になります。
「テストの使い方」は大変共感できる考えであり、その考えをヒントとして与えてくれたきょんさんにこの場を借りてお礼を申し上げたいと思います。
ソフトウェアのテストとは
ソフトウェアテストとは一体何でしょうか?
Wikipedia には以下のように書かれています。
ソフトウェアテスト(software test)は、コンピュータのプログラムを実行し、正しく動作するか、目標とした品質に到達しているか、意図しない動作をしないかどうかを確認する作業のことである。
いわゆる V 字形開発モデルであれば大きく「開発工程」「テスト工程」に分かれてソフトウェア開発プロジェクトは進むと思いますし、その後半の検証過程を「テスト」と呼ぶことが多いでしょう。しかし、このエントリでは少し違った方向性から「テスト」を捉えてみたいと思います。
テストの使い方
テストには様々な分類方法があります。
例えば「機能テスト」「セキュリティテスト」「性能テスト」「ユーザビリティテスト」のようにテストの種別(テストタイプ)で分類することもありますし、「ユニットテスト」「結合テスト」「システムテスト」のようにテストする範囲(テストレベル)で分類することもあります。
また、アジャイルテスティングでは【技術視点⇔ビジネス視点】【開発支援⇔製品評価】という二軸でテストを分類する次のようなマトリクスもあります。
http://tutoi1969.up.seesaa.net/image/matrix_06.png
もちろんこれらの分類にはちゃんと意味があって広く用いられているのだとは思いますが技術の発展や組織のあり方の変化にともなって意味を失った部分もあると考えています。
そこでもっとシンプルに「そのテストで何をするのか?」にもとづいて分類する方法が「テストの使い方」です。 これは「定義」「検査」「探索」「測定」の 4 つのテストがあります。
定義
- 定義のテストとは「何を作るのか」を決めるためのテストです。
- TDD で実装するテストケースは典型的な定義のテストですね。
- スクラムの「完了の定義」(Definition of Done)も定義のテストになるでしょう。
検査
- 検査のテストとは、構築されたソフトウェアの欠陥を探すためのテストです。
- 同値分割/境界値分析、ブラックボックス/ホワイトボックステスト、ディシジョンテーブルなど、いわゆるソフトウェアテスト技法が必要とされる領域になります。
- 単にスクリプトテストを実施して動いてることを確認するだけではなく、積極的に欠陥(バグ)を見つけにいく行為だと言えます。*2
探索
- 構築されたソフトウェアのことをより深く知り開発チームやプロダクトオーナーの知見を増やすために仕様として定義されていないことを試みるテストです。
- 「○○のケースについて考慮してなかったけど、この場合どうなるのですっけ?」という問いに答えるために実施します。
- この種のテストの結果は定義のテストとしてフィードバックされるか、測定のテストのテストケースの材料になることが多いでしょう。
測定
- 構築されたソフトウェアが実際にそれを使うユーザに価値提供できているかを確認するためのテストです。
- 定性的なテストと定量的なテストがありますが、前者はユーザインタビューや被験者によるユーザビリティテスト、後者はA/Bテストやアクティビティ分析などが該当します。
- プロトタイピング、ベータ公開、ドッグフーディングなども測定のテストと捉えてもいいかもしれません。*3
テストとは開発プロセスそのものである
さて、このようにテストを分類すると、テストとはソフトウェア開発における一工程ではなく、テストこそが開発プロセスそのものだと言えるのではないでしょうか。
何を作るかを決めて、実際に開発をして欠陥を見つけ、そのプロダクトやドメインに関する知見を得て、そしてユーザに公開して反応を見る、これはソフトウェア開発を行っているのであれば必ずやっているであろうプロセスであり、そのそれぞれのプロセスにおいてテストを有効に使うことはできます。
この考え方にもとづけばもしかしたらこれまで多くの人が「テスト」と認識していなかったもの*4もテストと呼ばれることになるのですが、実際それがテストであるかどうかにはあまり興味がなくて、それがプロセスとして価値があるかどうか、もっと言うとプロダクトの価値に寄与してるかどうかが大事だと思います。
プロダクトの性質による各テストのばらつき
僕がこの考え方が好きな最大の理由はおそらく、プロダクトやチーム、もっと言うとその業界のあり方を「テスト」という共通語を用いることによって考えやすくなると感じていることです。
例えば僕自身は現在 Web 系の受託開発を仕事にしていますが、そこでは”測定”のテストはほぼありません。納品がゴールであるというビジネスモデルにおいてそもそもイテレーティブな改善はできないし必要もないからです。その裏返しになりますが、”測定"が現実的にほぼ不可能だからこそ”定義”が非常に重要になりますし、”検査”も同様に重要になります。作るべきものをしっかり決めて、それを不具合なく構築することが価値であるというプロセスのあり方です。
方向性は同じではありますが、より”検査”が重要視されるだろうと思うのが金融システムのようなミッションクリティカル系か、組み込み系システムだと思います。何かが起こった場合のダメージが大きいシステムではどんなに生起確率が低くても”検査”で不具合をあぶり出す必要があります。組み込み系システムも一度市場にリリースしたらその後の回収コストが甚大なため同様です。
また、それとは真逆だと感じるのはいわゆるスタートアップの世界でしょう。ユーザが何を求めているかわからない、不具合なく構築してもそれが価値を生むかわからないという状態では”定義”や”検査”よりもまず”測定”が最重要視されます。そこから市場や競合の知見を得て初めて”定義”が可能になるわけです。
このように一口に「開発プロセス」と言っても業界やチームのあり方によって各プロセスの重要性は明らかに異なります。その際に「各プロセスがどの程度厳格に管理されているか」「重要なプロセスは自動化されているか」などの観点からプロセスを改善していくヒントを得るという意味で「テストを使う」というのは非常に価値があることなのです。
まとめ
きょんさんからいただいた話をもとに僕なりに咀嚼してエントリにしてみました。
くどいですが、この考え方・捉え方は僕はとても共感しており、もっといろいろな方向性で役に立つと思っています。例えばこれを何かしらのフレームワークやパターンランゲージとして体系化することもできると思いますし、正直このエントリだけではすべてを語り尽くせてないと思っていますので引き続き発信していきたいと思っています。よろしくお願いします。
バトンタッチ
続いては hayabusa333 さんです。よろしくお願いします!