Test Automation

テスト自動化とか品質とか勉強会とかやってるエンジニア(Automation Architect)のブログです。

システムテストフェーズで単体テストレベルを実行する?!

テストフェーズとテストレベル

昨日受けたソフトウェアテストの資格試験で面白い問題があった。

縦軸にテストフェーズ、横軸にテストレベルをとってテスト計画を作れ

という趣旨のもの。

システムテストフェーズで単体テストレベルのテストを実行する?!

みたいなw

 継続的システムテストのコンセプトが一般的にまだまだ理解されにくく、その原因は

  • Myersの言う「テストフェーズ」[1]
  • Beizerのいう「テストのスコープ・観点(テストレベル)」[2]

あたりを混同しているエンジニアが多いからなのかなとちょうど考えていたので、この問題は僕の心にクリティカルヒットした。このブログエントリでは、継続的システムテストをテストフェーズとテストレベルから整理し直してみる。

継続的システムストのテストフェーズとテストレベル

継続的システムテストのテストフェーズ

継続的システムテストでは、

 ・開発テストフェーズ  (開発者の行うテスト)

 ・システムテストフェーズ  (テストエンジニアの行うVerification)

    ・ユーザーテストフェーズ  (プロダクトオーナーなどが行うValidation)

の3つのテストフェーズがある事を前提としている。

 ここでのテストフェーズはMyersが言う通り、テスト活動の時間的順序を表しているわけではなく、工程の実施時期が重なっても構わない[1]。例えば自動化が進み1日に何回もデプロイとテストしているような環境であれば、これらのフェーズはそのほとんどが重なり平行に実施されるようになる。

 フェーズがほとんど重なるのであれば、フェーズを分ける事のメリットは何だろう?という疑問が湧くと思う。フェーズを分ける事のメリットは、それぞれのテストフェーズによってもたらされる価値が明確になる事だ。この3つのテストフェーズは、ソフトウェア開発ライフサイクル内の実施される時期にもとづいて、それぞれ異なる価値をプロジェクトに提供する。

 開発テストフェーズは開発者に「素早く実装可能な開発環境」という価値をもたらす。ユーザーテストフェーズは「ユーザーに価値のある正しい機能が提供されているか?」を確認する。

 継続的システムテストが主眼を置くシステムテストフェーズの価値は3種類の受け取り手が存在する。

  • 1つ目は開発者。継続的にシステムテストを実行し素早くテストからのフィードバックをする事で、開発者はバグの修正を短縮したりと開発のアジリティが向上する[3]。
  • 2つ目はプロジェクトマネージャー。継続的にテストを実行しそのメトリクスをモニタリングする事でプロジェクトの進捗状況が見える化される[4]。
  • 3つ目はユーザーテストの担当者。ユーザーテストフェーズの準備ができている事をシステムフェーズが保証する事で、ユーザーテスト環境の安定性が向上する。

継続的システムテストのテストレベル

 継続的システムテストでは、各テストフェーズがそれぞれ適切なテストレベルを持っている。ここでいうテストレベルはBeizerの言う「テストのスコープや観点」だ[2]。なので、例えば

システムテストフェーズの中で

  • 「単体テスト」や「インターフェースの結合テスト」といった低レベルのテスト
  • 一般的にテストレベルの文脈の中でシステムテストと呼ばれる「パフォーマンステスト」「信頼性テスト」「運用性テスト」
の両方を実施する

という、言葉的には少し奇妙な事態が発生する。

 しかし、この一見すると少し奇妙な現象がもたらすメリットは大きい。システムテストフェーズでも、単体テストレベルからシステムテストレベルまでのテストレベルを網羅する事で、

  • テストの網羅性を担保する事
  • 柔軟にテストレベルを変更したり、テスト設計のリファクタリングを行うことででテスト活動を効率化する事

が可能になる[5]。

アジャイルテストと従来のソフトウェアテスト

 勘のいい人はお気づきだと思うけれども、僕は継続的システムテストは継続的デリバリーと同様にアジャイルテスト四象限と自動化にのっとってテストを整理し直したコンセプトだと考えている[6]。

 アジャイルテスト四象限では「誰に」「どんな」価値をテストが提供するのかを考える[7]。次にそれらの価値の提供を「いつ」「どのスコープのテスト」によって実現するのかを考える。

 この『「誰に」「どんな」価値を提供するのかの部分が『V&Vとテストフェーズだし、『「いつ」「どのスコープのテスト」』の部分が『「テストフェーズ」「テストレベル」』だ。

 これらのコンセプトや考え方は別にウォーターフォールやテスト自動化を前提としていない[8][9]。もちろんウォーターフォール開発でも実現可能だが、継続的デリバリーやアジャイルテストにおいても実現可能だ。

 継続的システムテストやアジャイルテスト四象限は従来のテストの考え方を積極的に取り入れている。突然変異的に生まれたものではなく、むしろソフトウェアテストの発展の歴史の中で正統的に出てきたものだ。

お知らせ

継続的システムテストについて2015年9/18(金)にソフトウェア品質シンポジウムでお話しします。ご興味のある方は是非ご参加ください。

www.juse.jp

参考文献

手動の運用手順書と自動スクリプトのレビュー

 先日、「手動の運用手順書を書いたのでレビューして下さい」と後輩に頼まれたのでレビューした。といっても、僕の専門はテストと自動化なので正直な話、手動の運用手順書のレビュー経験がない(笑)。しょうがないので「自動スクリプト」としてレビューするよと断りをつけてレビューした。

 実際、レビューしてみると手動の運用手順書と自動運用スクリプトのレビュー観点やその方法は共通する部分も多いが、その一方で前提や観点の違いから気をつけないといけないと感じた事も多かった。

共通する点

レビューの目的

 本番運用フェーズに入っているシステム上でシステム変更を実施する事は、システム上で予期しない変更をもたらし障害を引き起こすリスクを伴う。このリスクは手動でも自動化でも変わらない。システム変更に関するレビューの一番大事な目的は、 システム変更に伴うリスクが管理可能になっているかを確認する事だと思う。

 一般的に以下の点については、手動の運用手順書でも自動運用スクリプトでも、明確に記載されているか、その考え方が分かるように表現されているべきだと思う。

  • システムの変更箇所 (例 機能A
  • 影響範囲 (例 機能B
  • リスクのリスト (例 機能Bがデータの不整合により動作しなくなる事
  • リスクが顕在化する事なく、システムへの変更が終了した事を確認する方法 (例 機能AとBが期待通りに動作する事
  • リスクが顕在化した事を確認する方法 (例 機能Bのログファイルにエラーログが出ている事
  • リスクが顕在化した場合の対応方法 (例 データの不整合の解消

 これらを事前に明確にしリスクを管理可能にする事で、手動の運用手順書も自動運用スクリプトもその信頼性が向上する。

ロールバック

 システム停止を伴うシステム変更は、短い運用作業時間、少ないシステム停止回数で行う事が一般的に求められる。なので、複数のシステム変更を一度に実施する事は多い。ここで気をつけなければならない事は、複数のシステム変更はロールバック不可能な状況を引き起こす場合がある事だ。

 例えば変更A,変更B,変更Cを行う時に、変更Aと変更Bの後にはまだロールバック可能だが、変更Cの後にロールバック不可能になる事はしばしば起こる。

  • 一回のシステム変更で実施: [変更A → 変更B → 変更C] (ロールバック不可能)
  • 複数のシステム変更で実施: [変更A] (ロールバック可能)→ [変更B] (ロールバック可能) → [変更C]  (ロールバック不可能)

 ロールバックはデプロイに際しリスクを回避するための重要かつシンプルな手段だ[1][2]。だから、そのロールバックのポリシーが適切であるかをレビューで確認する事は重要だ。

異なる点

エラーに対する対応方法

 実行したコマンドに対して期待と異なる挙動が返って来た場合、手動の運用ではその場で人間による柔軟な対応が可能だが、自動スクリプトでは事前に定義した対応方法しか機械は実行出来ない。手動の運用ではエラーケースへの対応方法が手順書には表現されていなくても暗黙知として共有されていれば十分な場合があるが、自動スクリプトではすべて形式知化していく必要がある。

 ネガティブテストとそれらのテストで失敗した場合の対応方法が十分に定義されていない自動スクリプトは、悲惨な結果をもたらしかねない。自動運用は信頼性が低いと一部で指摘される理由はここにあるだろう。

 ただ、このあたりはもうすでに何年も前に解かれている問題だとも思う。例えばJavaでは、期待と異なる状況が起きた時には適切なExceptionを投げ、プログラムの適切な場所でCatchし対応を行う。JUnitではテスト実行中にExceptionが発生しても後処理を確実に実行するフレームワークを提供する。

システムの状態に関する前提

 もうすでに何年も前に解かれている問題であると言っても、実際にすべてのエラーケースを事前に網羅的に定義して行く事は難しい。システムの設定が複雑になるとテストすべきポイントは増える[4]。 特にシステムの状態について複数のケースを考慮しなければいけない場合や、コマンドを複数回行った場合に得られる結果が異なる場合等には、考慮すべきエラーケースの数が爆発的に増加する。

 この問題を解決するための考え方が、"Immutable Infrastructure", "Infrastructure as Code", "冪等性"だ[3]。システムの状態を適切にバージョン管理し、なりうる状態に制約を入れる事で、システムの事前状態をコントロール可能にする事が出来る。また、システム変更を実施する前にシステムの事前状態を確認し、適切な事前状態の時のみに変更を実施する事もエラーケース数の爆発を抑えることに役立つ。

 手動運用の場合も、もちろんこれらの考え方を適用する事は可能だが、その一方で手順書の効率化等から暗黙知化されていたり、逆に職人芸と化した手順書となっていたりする。手順書レビューでは、明確に表現されていないシステムの事前状態がないかの注意が必要だ。

 レビューとテストの使い分け

 僕が今回のレビューで一番戸惑った部分がここだ。自動スクリプトでは殆どの場合、自動テストも一緒に書かれる。自動テストがあると、テストとレビューそれぞれでカバーしたい範囲について簡単に議論が出来るのでそれぞれの役割が明確になりやすい。例えば、ファイルをコピーするコマンドと、コマンドの実行結果を確認するテストがある場合、自動テストを実行するだけでコマンドの正しさを確認する事が出来る。

 手動の手順書でも"#テスト済み"などとコメントを書く事で 、ある程度テストとレビューの役割を区別する事が可能かもしれないが、自動テストがないために、ついついコマンドの正しさが気になってしまう。

 レビューでは人間にしか確認出来ない事に集中する事が大切だ。コマンドの実行結果の正しさのような自動化する事で機械でも確認出来る観点ならばそちらに任せてしまった方がいい[5]。"レビューの目的"の項でも挙げた「システム変更に伴うリスクが管理可能であるかを確認する」といった人間にしか確認出来ない観点に集中しやすいという点においては自動スクリプトに分があると思う。

まとめ

 システム変更に関するレビューにおいて、手動の運用手順書と自動スクリプトで、

  • システム変更に伴うリスクが管理可能になっているかを確認する事という目的は共通

であるが、

  • エラーに対する対応方法やシステムの事前状態に関する前提が異なるため、気をつけるべきポイントが異なる

事について述べた。

 今回、それぞれの手段でのレビューに共通、異なるポイントという切り口で書いたが、これらのポイントは手動運用手順書を自動化する際の切り口として扱う事も出来る。これらのポイントを適切に解いて行く事で、より幸せな運用自動化が実現可能になると考えている。

参考文献

 

テストの期待値を分解すると言う事 ~Web Service QA Meeting Vol.1の感想~ #webqa

 本日、Web Service QA Meeting Vol.1という勉強会に参加して来た。様々なウェブサービス企業のQA関連企業で集まって、WebのQAについてあれこれ話そうよと言う勉強会だ(と思う)。

 ま、僕の悪い癖は「面白いな」と思った話については議論を盛り上げたいと思うと言うか、いわゆるマサカリを投げたくなる事なんですが(笑)

 マサカリ話はいったん置いておいて、面白いなと思った話について書いてみる。

 僕が面白いなと感じた発表の趣旨は僕の言葉で説明すると「テストの実行時間が長いので、テスト観点とテストレベルを見直し、適切なテストレベルで実行する事でテストの実行時間を短縮した」になる。別の言い方をすれば「アジャイル4象限の右上で実行していたテストを左上で実行する事で効率化した」だ。(発表者ならびに関係者の皆様、僕の理解が間違っていましたらゴメンナサイ。連絡頂ければ訂正します。)

 この発表で僕が面白いと感じたのは上の「テスト観点とテストレベルを見直し」の部分を「テストの期待値を分解し」と説明していた点だ。そう、1つ1つのテストケースについてテスト設計が終わった後でも期待値を分解する事は実施してもいい(のかもしれない)

 期待値を変更してしまうと、テストの網羅性の再評価等のテスト設計のやり直しに相当する作業が発生する可能性がある。けれど期待値を分解し、分解された期待値をテスト観点を元に整理し直すだけならば、テストの網羅性には影響がない。この発表の肝はまさにテスト設計のリファクタリングをやっている事だと思った。

 テスト設計は一度作ったら終わりではない。機能の設計をリファクタリングを通じて改善して行くのと同じように、テスト設計も継続的に改善して行くものだ。テスト設計の継続的な改善を通じてサービスの成長に貢献出来る事がウェブサービスのQAの醍醐味。そんな事を考えた実りある勉強会でした。

2015年前半戦 いいなと思った記事やスライドの個人的ブックマーク

2015年前半戦いいなと思ったインターネット上の記事やスライドを個人的にブックマークしときます。

コンセプト+ テクノロジー

 

コンセプト

アーキテクチャとかデザインパターンとか

テストとか品質とか

Docker

 

 

ソフトウェアテストなんて誰でも出来る

アマチュアとプロフェッショナル

 先週参加したカフェソフトウェアクオリティのお悩み相談コーナーで、「ソフトウェアテストなんて誰でも出来ると思われている」というものがあって笑った。

「○○なんて誰でも出来る」というフレーズは何にでもあてはまってしまう。

例えば

  • キャッチボールなんて誰でも出来る
  • ギターなんて誰でも弾ける
  • 英語なんて誰でもしゃべれる
  • サラリーマンなんて誰でも出来る
  • プログラムなんて誰でも書ける

などなど。

 結局これってアマチュアとプロフェッショナルの違いについての議論だ。

 テストエンジニアがその存在価値を認めてもらうには、プロフェッショナルな開発者やマネージャーには提供出来ない、プロフェッショナルなテストエンジニアだけが提供出来る価値、組織にもたらす利益を突き詰めるしかない。 

 プロフェッショナルなテストエンジニアの役割

 僕が最近感じるプロフェッショナルなテストエンジニアの役割を列挙してみる。(ここではテスト設計やテスト計画等の専門用語は使わない。)

バグを見つける

バグを見つける事は、それを見逃しリリースしてしまった時の損失を防ぐ事に直接つながる。損失をもたらすバグをテストで見つける事はソフトウェア開発プロジェクトにおいて最重要の役割の1つだ。

無駄なテストをしない

いくら徹夜で頑張って大量のテストを実施したからってバグをみつけられなければ、それはプロジェクト全体から見ればコストとしか見られない。無駄なテストをしない選択をする事も重要な役割だ。

バグを見つけるタイミングを計画する

「どんな」バグを見つけるかと同じくらい「いつ」バグを見つけるかも重要だ。プロジェクトが終るタイミングで見つけたって遅すぎる。適切なタイミングでバグを見つけるように計画するエンジニアはプロジェクトの進捗の円滑化をしてくれる貴重な存在だ。

バグに関する知識の蓄積

テストは失敗する事をチェックして終わりではない。バグの特定とバグの修正をする必要がある。バグに関する知識や経験を多く持つテストエンジニアは、バグの場所を特定したりバグの修正方法について、品質を向上させる為のアドバイスをする。

開発者とテストエンジニア

  「ソフトウェアテストなんて誰でも出来る」なんて開発者に言われるのかしら。もしそうならば僕ならテキトーに言い返すなあ。「バグなんて誰にだって作る事が出来るw」と。

 ま、実際にはバグだって「誰にでも作れるバグ」と「プロフェッショナルな開発者にしか作り込めないバグ」がある。昔、あるプログラムの1つの処理のテストとして作って実行した5万件のうち1件だけ失敗した時には、自分もすごいと思ったけれどもそのプログラムの開発者もすごいと思った。どうしたら、そんな複雑なバグが作れるのだwと。 テスト結果を見せた時はその開発者も「いいテストするねー」と笑ってた。

 開発者はその最大限の想像力でプログラムを書くし、テストエンジニアは開発者の想像力のギリギリのところを狙ってテストをする。プロフェッショナルな開発者とテストエンジニアの関係ってそういうものだと思う。

アジャイルテストのテスト設計の話

Incremental test design

 昨年度追加されたISTQBのFoundation Level Extension Syllabus Agile TesterのAgile Testing Practicesの項にはテスト設計に関する興味深い記述がある [1]。

Incremental test design: Test cases and charters are gradually built from user stories and other test bases, starting with simple tests and moving toward more complex ones.

アジャイルテストのテスト設計の特徴として

  • ユーザーストーリーをテストベースとして用いる事
  • シンプルなテストケースの追加から始まり、より複雑なものへと変化して行く事
  • Incrementalである事

が挙げられている。

アジャイルテストについておさらい

 アジャイルでは顧客に価値を届ける最小単位の要求をユーザーストーリーと呼ぶ。スプリント等と呼ばれるタイムボックスの中で、複数のユーザーストーリーの開発を行う[2]。

 アジャイルテストではこのユーザーストーリーをテストベースとして用いる。ユーザーストーリーに記載されている顧客目線でのシステムの期待される振る舞いを、テスターはテスト可能なストーリーへと変換する。ExampleやBDDなどの記法とコミュニケーションを通じて顧客、開発者、テスター間で期待するシステムの仕様について合意する[3]。また、シンプルなハッピーパスのテストから始め、そのテストがパスしてからエッジケース等の複雑なテストケースに進む[4]。

 厳密にはアジャイルテストではないが、アジャイルテストの原型となっているのがテスト駆動開発(TDD)だ。テストを先に書く事によってレビューとリファクタリングを繰り返しながら設計を改善していく事が可能であると言われている [5]。

 アジャイルテストにはもう一つ、アジャイルテスト4象限という大切な概念がある。アジャイルテストが取り扱うテストを4つのグループにカテゴライズし、テスト計画を立てて行くというものだ[6]。

  • 開発者のためのテスト=内部品質
  • 顧客のためのテスト=利用時品質

のようにカテゴライズし、それらのテストをいつどのように実施するか計画を立てる事を推奨している。

アジャイルテストのテスト設計の特徴

これらを踏まえ、アジャイルテストのテスト設計には以下の特徴がある。

顧客のテスト設計への参加

 アジャイルテストでの重要なテスターの役割は、顧客のビジネス的なシステムへの要求を非エンジニアである顧客にも理解可能なExampleやテストに変換する事だ。これにより、テスト設計への顧客の参加が可能になる。

開発開始前のテスト設計の実施

 アジャイルテストではスプリントの開始前、つまり開発の開始前にテスト設計を行い顧客、開発者と合意する。ここでいうテスト設計は一般的な意味での網羅的なテスト設計ではなく、

  • テスト観点の洗い出し
  • Happy path(やCritical path)のExample

のみしか含まないかもしれないが、あえてここではテスト設計と書く。

 これはテストプロセス視点で見ると、テスト設計を通じて仕様についての抜け漏れや間違いのレビューを早期に実施している事になる。

ユーザーストーリーとテストの追跡性

 ユーザーストーリーをテストベースとしてテスト設計を行うため、ユーザーストーリーとテストの追跡性が担保される[7]。そのため、ユーザーストーリーへの変更要求に起因するようなテストスクリプトへの変更や、ユーザーストーリーレベルでのテスト設計の変更が容易であるという長所がある。また、ユーザーストーリーの範囲で、単体テストやコンポーネントテストの継続的なリファクタリングが行われる[8]。

Happy path から Edge caseへ

 Incrementalなテスト設計と呼ばれる理由の一つがここにあると考えている。アジャイルテストでは、スモークテストで実施するようなhappy pathのテストとedge caseのテストのテスト実施を段階を分けて行う。実際にはテスト実施だけでなく、テスト設計も段階を分ける事が多い(と身の回りでは感じる)。

 テストの優先順位付けを行いリスクの大きいバグを早期に発見する事で、より俊敏で安定した開発•テストプロセスを築く事が出来る。

スプリントごとのアドホックなテスト設計の追加

 アジャイルテストのテスト設計がIncrementalであると言われるもう一つの理由がここにあると考えられる。テスト設計はスプリントの開始前にユーザーストーリーをテストベースとして実行される。そのため、テスト設計はスプリントごとに追加される。

アジャイルテストのテスト設計が苦手な事

 こうやって書いてくると良い事ずくめに感じられるアジャイルテストのテスト設計だが、これらの特徴に起因する苦手な事が存在する。

スプリントをまたいだ機能のテスト設計が苦手

 ユーザーストーリーをテストベースとしてテスト設計を行うので、どうしてもスプリントをまたいで実現される機能のテストが苦手という特徴が生じる。この弱点は通常は問題にはならない。優秀なプロダクトオーナーやアーキテクトは、システム要求をよしなに分割してストーリーは作られているはずである。例えば、機能BとCが機能Aに依存している場合、

  • スプリント1: 機能A の開発とテスト
  • スプリント2: 機能B の開発と 機能AとBの結合テスト
  • スプリント3: 機能C の開発と 機能AとCの結合テスト

といったように。しかし、ここで、

  • スプリント1: 機能AとCの一部を開発
  • スプリント2: 機能BとCの一部を開発
  • スプリント3: 機能AとBの一部を開発

のように、ユーザーストーリーがきちんと整理されていないと、結合テストをいつやるか?結合テストのスコープは何か?といった問題が生じる。(そんなのScrumじゃないと言ってしまえばそこまでだが、Scrumじゃない事を見落とすと非効率なテスト設計の本質を見失う。)

スプリントをまたいだテスト設計の最適化が苦手

 テスト設計の重要な役割として、テストカバレッジを担保しながらテストケース数を減らすテストの経済学の考慮がある[9]。しかし、アジャイルテストではスプリントをまたいだテスト設計の最適化が苦手である。

 何故か?第一にユーザーストーリーに対するカバレッジを100%にする事を大前提としている事、次にユーザーストーリーに対する追跡性を重要視しているため、システム全体でどのようなテストがどれくらいの規模で行われているのかを可視化する事が苦手な事に起因している。

 例えば今回のスプリントで追加した10件のテストケースによって、前回のスプリントで作成した100件のテストのテストケースを削除しても同等のパスカバレッジを担保出来るといった状況であっても、一般的にテストケースの最適化は行われていないのではないかと思う。

 こう考えている理由は、○○百億件のテストを自動化しナイトリービルドで実行しているエンジニアから「実はテストケースの減らし方が分からない」という話を聞いた事があるからだ。この会社では、テストの最適化をテスト実行の優先順位付けで行っているのは有名な話だ。

 また、実践アジャイルテストの 著者のJanet Gregoryの"Traceability"というタイトルのブログエントリが興味深い。ユーザーストーリに対する"Traceability"そのものは重要だが、"Traceability Matrix"のような全体を俯瞰するための表はいらないと述べている[10]。

アーキテクチャのテスト設計が苦手

 賛否両論あると思うが、アジャイルテスト4象限の第4象限に非機能要件のテストが定義されているのにも関わらず、アジャイルテストは非機能要件のテストが苦手だと指摘されている[11][12]。

 この問題は根が深い。アーキテクチャが自律的に、継続的に進化するのであれば、当然その反映であるシステムの品質、例えばパフォーマンスや運用性と言った品質も継続的にテスト、モニタリングされる必要がある。

 これは、アジャイルでのアーキテクチャの肩身の狭さのため、アーキテクチャの反映であるシステム品質がおろそかにされがちな為なのでは、と考えている。この問題の解決策として、パフォーマンスやユーザビリティ等の非機能要件もユーザーストーリとしてバックログに追加する事が提案されている[13]。

まとめ

 アジャイルテストではユーザーストーリーを中心に据える事で、

  • 顧客がテスト設計に参加
  • テスト設計を通した仕様のレビューの前倒し
  • Incrementalにテスト設計

をし、アジャイルなテスト設計を実現している事を挙げた一方で、

  • スプリントをまたぐテスト設計の最適化
  • ユーザーストーリーとの関連が低いアーキテクチャ等の品質のテスト

が苦手な事を述べた。

 アジャイルテストを導入するにあたっては、その長所はもちろんだが苦手な部分についてもきちんと考慮する必要がある。苦手な部分を無視するとテストの作り過ぎによる炎上やテストの抜け漏れを引き起こす。それらにきちんと対処すれば迅速で安定したテストプロセスの構築を可能にする。

 一方でこれらのアジャイルテストのテスト設計の苦手な部分は、これからアジャイルテストが体系化していくにあたっての課題であると考えられる。現在までアジャイルテストはどちらかというと「開発者側のもの」という印象があったが、これらの課題を解いていくにはテストや品質のスキルも必要になると考えられる。

リフェレンス

2次元の表によるテスト管理の限界

ソフトウェアテスト業界の古き大発明

 どの業界にも大発明が起きる瞬間がある。オーディオ業界のステレオスピーカー、映像業界のDVD、携帯電話業界のソフトウェアインターフェースなどなど。これらの破壊的な発明はそれまでの常識を覆し、全く新しい利便性や効率性をもたらす。過去使われていた方法は淘汰され、長期間に渡って多くの人に親しまれる。こういった大発明は劇的に世界を変える一方、多くの人に長期間親しまれてきたため、次に起きそうな革新を阻害するという事がしばしば起きる。誰だって長期間親しんで来たものが変化する時には少なからずの抵抗を覚える。

 「2次元の表によるテスト設計とテストケースの管理」はまさにこれにあたる。これだけ多くのテスター、テストアナリスト、テストマネージャーに親しまれ、長く使われて来たのはおそらく「革新的な発明」であり「とても便利なツール」だったからだ。しかし、次世代のテストを考える場合、この大発明を棄てる事も選択肢として考えなければならない。

2次元の表

2次元の表によるテスト管理の特徴

 様々な情報をすべて2次元の表に詰め込む。これが2次元の表でテストを管理する事の特徴だ。以下のような異なる属性が一つの2次元の表で管理されているテスト設計をみなさんも見た事があるのではないだろうか?

  • テスト環境
  • テスト観点
  • テスト条件
  • テスト技法
  • テスト事前条件
  • 期待値
  • テスト手順

すべての情報が一つのテーブルによって表されている事が大きな特徴だ。

2次元の表によるテスト管理の利点

 すべての情報が一つのテーブルによって管理されているので全体の見通しが良いというのが大きな利点の一つだ。特にマネージャーはこのテーブルを見るだけで、どのようにテストしているのか一目瞭然に分かる。テスト観点やテスト条件を見れば何をテストしているのか分かるだろうし、テスト手順や技法を見ればどのようにテストしているのか分かる。

 また、この2次元の表によるテスト管理の利点としてもう1点、テスト設計者とテスト実行者を分ける事が可能になる事がある。 なるほど。どこかで聞いたような話だが、テスト設計とテスト実行の役割を明確に分ける事により、テスト実行の部分をスケール出来るようにする。「人月の神話」を信じているような、レガシーな大規模開発ではありえそうな話だ。

利点の前提条件

 しかし、この利点を効果的に得る為には一つの条件が前提となる。それはテスト設計に変更が入らないという事。少し条件を弱めれば、テスト設計の時点でテスト設計への変更要求がある程度予測可能である事である。

 ウォーターフォール開発が一般的であった時代には少なくともプロジェクトマネージャー、アーキテクト、QAマネージャー間では合意可能な前提であったのだと思う。しかし、アジャイル開発のようなテスト設計への変更要求が大前提の開発スタイルではいくつかの大きな問題を引き起こす。

2次元の表によるテスト管理の問題点

①テスト条件の追加•変更更要求に対し、変更箇所が多い

 テーブルを非正規化してしまっている事の弊害として、テスト設計変更要求に対して変更箇所が多いというメンテナンス容易性の問題がある。例えば、新しい仕様の追加によりテスト条件を1カ所追加したい場合、正規化しているテーブルに対してならば1カ所だけ変更するだけで済むものも、非正規化しているテーブルに対しては、select文で条件に合致するレコードを抽出し、条件に合致するレコード全てに対してテスト条件を追加する必要がある事と同じ問題が起きる。

②テスト設計の継続的改善が難しい

 また、テスト設計の継続的改善が難しい事も問題である。テスト設計は一度実施したら終わりというものではなく、継続的に改善する必要がある。これには2つの理由がある。

  1つ目の理由は、テストの実行結果によってテスト設計も改善する必要がある事である。テスト実行前にバグを発見可能と予測して作ったテストケースと、実際にバグを見つけたテストケースとの間にはきっと差分がある。その差分によりテストケースを追加する事は当然であるが、加えてテスト設計も見直す必要がある。

 2つ目の理由は、プロダクト側のアーキテクチャ変更に伴うものである。アーキテクチャが変われば当然求められる品質も変わる。テスト設計自体を変更する必要性が生じる。

③テスト自動化への移行の問題

 テスト自動化が成功していない事例をいくつか見たり聞いたりしてきたがその原因の一つに、手動テストが前提の"テスト設計者"と"テスト実行者"のロールモデルをそのままに、テスト自動化プロジェクトを実施したというものがある。

 よく聞く「手動のテスト実行よりも、テストスクリプトの実装の方がコストが高い」という話。今まで通りのテスト設計をして、テスト実行をテスト実装で置き換えるという前提であれば、その比較は正しい。しかし、僕はこの比較についてかなり懐疑的に考えている。「手動テストに最適化されたプロセスのコスト」と、「自動テストに最適化されていないプロセスのコスト」の比較にどんな意味があるのだろうか?

 テスト自動化へ移行する場合、少なくとも

  • テストスクリプトを実装するエンジニアにとっての必要最低限な情報は何か?
  • テスト設計プロセスの中で、テスト実装者が実行した方がプロセスが最適化されるものは何か?

についての議論を踏まえ、自動テストに最適化されているプロセスを定義し比較する事が必要である。

まとめ

 僕はこれらの「2次元の表によるテスト管理の限界」について、テスト設計がリファクタリング不可能である問題、とこれから呼ぶ事にする。

 継続的インテグレーションが導入されているプロジェクトでは、リファクタリングを定期的に行い技術的負債を返済しながらプロダクトの品質改善を行うのと同様に、テスト設計も定期的に改善されていかなければならない。そう、きっとテスト自動化プロジェクトとスクラムはとても相性がいいのだ。

 次回のエントリでは、アジャイルテスターの人達がどのようにテスト設計とそのリファクタリングについて考えているのか、何も考えていないのか、について書く。

参考情報

http://qualab.jp/materials/SOFTEC2012-2.pdf

JaSSTソフトウェアテストシンポジウム-JaSST'15 Tokyo レポート