構造を浮き彫りにするテスト
はじめに
今回はソフトウェアテストをソフトウェア開発の目的から2つに分類します。「構造を浮き彫りにするテスト」と「構造を決定するテスト」です。これは筆者独自の分類方法です。
これらは品質向上に対して相互補完的な関係にあり、それぞれのスキルの成長にも傾向があります。自身や組織に不足しているソフトウェアテストがどちらなのかを認識し、効率的に品質を向上させましょう。
今回は、まず「構造を浮き彫りにするテスト」の導入について解説します。
テストには2種類ある
効果的にソフトウェアテストを実践していくには、組織やプロダクトにとってのソフトウェアテスト自体を適切に構造設計することが必要です。その構造に従ってソフトウェアテストのスキルを組織的に成長させたり、その構造に従って各プロジェクトにおけるテスト戦略を位置づけたりしていきます。これらは個人にも組織にも納得感の高いことが重要です。
そういったソフトウェアテストの構造化において、筆者はまず分類としてソフトウェア開発における活動に着目しています。
筆者は、ソフトウェア開発中の活動は大まかに以下のようなものだと捉えています。そしてこれらを分解、統合しヒエラルキーを作って順序化したものが開発のプロセスであると考えています。
- Whatを決定する
- Howを決定する
- 実装する
- Howが正しいかを調べる
- Whatが正しいかを調べる
これらをテストという視座で捉え直すと、ソフトウェア開発においてソフトウェアテストは次の2つとして関わっています。
- 構造を浮き彫りにするテスト:ヴィジュアライズテスト
- 構造を決定するテスト:デザインテスト
1.の「構造を浮き彫りにするテスト」は、あるものがどのような形や手触りなのかを見えるようにします。これにより本来あるべき形や手触りと一緒なのか、本来あるべき姿を想定できていなかったのといった、「作ろうとしているものの欠陥」を明らかにします。
2.の「構造を決定するテスト」は、これから作るものの形や手触りがこうあるべきと定義します。これにより、本来あるべき形や手触りからズレることなくソフトウェアを開発できます。
これらの分類によってすべてのテストが排他的に振り分けられる関係ではありません。 「何のためにいつ作られたテストか」で分類します。そのため、テストケースとしては全く同じものが、状況によって構造を浮き彫りにするテストだったり構造を決定するテストだったりします。
例えば、構造を浮き彫りにするテストの例として、次のようなものがあります。
- セキュリティテスト
- パフォーマンステスト
- A/Bテスト
- 静的解析ツール
一方、構造を決定するテストの例としては、次のようなものがあります。
- TDD(テスト駆動開発)/BDD(振る舞い駆動開発)/Specification by Example(例示による仕様)
- セキュリティテスト
- パフォーマンステスト
ここで言う「構造」とはシステムの分類ですが、その際には特にいわゆる非機能がシステム構造に大きく影響すると考えています。逆に、いわゆる非機能を要因としたシステム構造を設計できていない場合には、改修するたびに開発コストが高くなってしまうでしょう。あとから構造を変更するにはコストがかかるからです。
システム設計における構造はいわゆる非機能が重要です。ソフトウェアテストによってさまざまな視点で構造を浮き彫りにし、構造を決定することで頑強なソフトウェアに近づけます。
一方、これまでソフトウェアテストの分類には、テスト対象の大きさで分別する「テストレベル」による「コンポーネントテスト」「統合テスト」「システムテスト」がありますが、今回解説しているのは、これらとは別の軸で分類したテストです。
既存のテストレベルによる分類も重要ですが、組織一体となってテストを実践すると考えると、ソフトウェア組織における活動で分類したテストのほうが都合が良いという考え方で、筆者は構造を浮き彫りにするテストと構造を決定するテストを好んでいます。
また、このような分類と近いものに「Testing」と「Checking」がありますが、Checkingはあまり価値を生まないなどの文脈があるため筆者はこの表現を好んでいませんし、意味も多少異なります。
仕様通りに作られているかを検査するテストの一部はCheckingだと捉えられますが、構造を浮き彫りにするテストの場合もあれば構造を決定するテストの場合もあります。「何のためにいつ作られたテストか」で分類するというのが筆者の主張です。
構造を浮き彫りにするテスト、構造を決定するテストの例
WebGUIのアプリケーションで、構造を浮き彫りにするテストと構造を決定するテストの例を説明します。図1のような構成のシステムがあったとします。
WebGUIで画面操作された結果をWebAPIで受け取り、DataBaseから情報を取得したり、結果を保存したりします。そして、この上でセキュリティテスト(もしくはセキュリティ視点でのレビュー)を実施すると、SQLインジェクションなり、不正な操作を行える文字列を入力できてしまう構造になっていることが判明したとします。つまり、システムが図2のような構造だったのです。
画面の入力文字列はWebGUI側のみでチェックされているため、curlコマンドのようなもので簡単にSQLインジェクションをはじめとする不正操作を実行できます。これが構造を浮き彫りにするテストです。
そして、このテストによってシステムの構造が図3のように決定します。WebAPIで必ず文字列バリデーションを行うことで、WebGUI以外からの入力でも不正操作ができないようになります。これが、構造を決定するテストです。
このように、構造を決定するテストが組み込まれているのがテストファーストやTDDといった手法です。「実行できるテストを実装してから、プロダクトを実装するという手順」は、まさに構造を決定するテストによってソフトウェア開発を推し進めています。
他にも、パフォーマンステストでボトルネックを見つけることは構造を浮き彫りにするテストですし、それらのテストを精査してシステム構造の特定部分の構造を決定するようなパフォーマンステストを実装し、TDDのように進めていくのは構造を決定するテストです。機能的なシナリオによるテストも、ある側面では構造を決定するテストと言えます。TDDを行う際には、まずこちらで進めることが多いです。
テストによって学習曲線が異なる
筆者の経験では、ソフトウェアテストの学習は領域によって効果が出始める時間がまるで異なります。これを先の2つの分類に当てはめると、図4のようになります。
- 構造を浮き彫りにするテスト:初期投資の割に高い効果が得られるが、すぐに頭打ちになり、しばらく投資してからやっと次の効果が出る
- 構造を決定するテスト : ほぼ線形(ゆるやかな線形)
構造を浮き彫りにするテストはテストツールが豊富なこともあり、初期投資ですぐに効果が出やすいですが、ツールで底上げされたところからさらに踏み込んで構造を浮き彫りにするためには多くの学習や経験が必要になります。還元主義的にモノゴトを分解して見られるようなスキルを身につけていくことと、俯瞰して要件と課題をつなげて見ていくスキルが必要になります。
構造を決定するテストはテストツールがあまり豊富ではない分、なかなか効果が出にくいですが、積み上げて学習していく内容が多いため着実に効果が出ていきます。常に検証範囲に入っているようなテストにするためのドキュメンテーションやコミュニケーションスキルが必要になります。自動化、ドキュメント、ペアテスティングのように、構造を決定するテストでは設計情報として扱うためのスキルが重要になります。システム全体の品質がなかなか上がらない、早期に設計の欠陥を発見できなくて困っているという際は、どちらかのスキルが不足している可能性を考えてみると良いでしょう。
まずは構造を浮き彫りにするテストから入るのも良い
もし、構造を決定するテストを実践していくことが難しければ、まずは構造を浮き彫りにするテストで大まかにソフトウェア構造を把握できるようにしてみるのも良いでしょう。
例えば、ツールを使うと次のようなことを簡単に行えます。
- 静的解析
- パフォーマンステスト
- セキュリティテスト
- 耐久テスト
- 構成テスト
テストツールは特定領域の標準やトレンドを形式知化したものなので、簡単に試して自分たちのプロダクトと比較してみましょう。これらのツールを上手く、適切に使いこなしていくには勉強や経験が必要になります。セキュリティやパフォーマンスは、コンピューティングシステムそのものに対する学習が不可欠です。
また、効率的なテストにするには、いくつかテスト技法を学ぶほうが良いでしょう。効果の高いテストを素早く実践できるようになるには時間がかかりますが、低コストで高品質を得るための重要なスキルです。とりあえずパフォーマンステストをやってみるならGatlingやh2loadなど、セキュリティテストではOWASP ZAPが簡単に利用できます。
ツールではありませんが、開発プロセスの変更が少ないものは次の2つです。
- コードレビュー(Pull Request)
- 手動によるテストやデバッグ実行
コードレビューは小さい粒度でシステム構造を見られますし、手動によるテストやデバッグ実行は手動でシステムを動作させてみることに効果があります。これらはアドホックに実施できることがメリットですが、より設計に近いため、見ているものを抽象化して構造化するスキルが幾分必要になります。
このようなテスト実行ツールによって構造を浮き彫りにしていくのが手っ取り早いですが、「本当に必要なテストを行えているか」という意味では、さまざまなテスト技法やリスク管理を学習する必要があります。
代表的なテスト技法には、次のようなものがあります。
- 同値分割/境界値分析
- ドメイン分析
- 組み合わせテスト
- リスクベースドテスト
もちろんこれだけではありませんが、「どうやって構造を浮き彫りにするのか」を中心に考えてテストを実践していくことが大切です。
おわりに
今回は、ソフトウェアテストをシステムの品質を向上するために必要な活動によって「構造を浮き彫りにするテスト」と「構造を決定するテスト」に分けて解説しました。
筆者の経験では、どちらかのテストスキルだけでは品質を向上するのに時間がかかりましたが、両方のスキルを活用・成長させていくことで効率的に品質を向上できました。
構造を浮き彫りにするテストによって大きな設計欠陥を発見したり、構造を決定するテストによって設計と実装のズレを減らしたりできます。
次回は、「構造を決定するテスト」としてTDDの導入について解説します。