WACATE2016夏に参加して、成長しそうな予感の私のテスト
テスト分析
分析の手順
やり方を以下のように、実行可能な作業単位に分けられていた点も、とてもありがたかったです。
- 分析方法を決める
- 情報を整理する
- 成果物を確認する
- 顧客の要求(テスト要求)を分析する
- 設計書(テスト対象)を分析する
- 分析結果を整理する
分析方法を決める
テストしたい「こと」? テストしたい「ところ」?
テスト分析の手順を振り返っていて、混乱してしまったのがここでした。
- "システム"(ドキュメントすべて)に対して分析をしたら、テストしたい"こと"、"ところ"って粒度が異なる"こと"、"ところ"がたくさん出るよなあ
- 粒度の違うテスト条件、どうやって整理するんだろう?
- 粒度が異なるから、それぞれの粒度か、テスト条件が一度にたくさん出てきてしまい、まとめきれないんじゃないの?
などなど
情報(分析する対象)の整理
ここで、この混乱を解く為に重要な鍵となるのが「情報(分析する対象)の整理」でした。
ここでの分析対象は、配布された資料です。
当日、テスト分析、テスト設計の為に配布された資料(顧客要求、仕様書)はたくさんありました。テスト設計まで行うので仕方のないことです。
ですが、これらを整理すると、いくつかに分類できることに気づきます。
- 新旧業務フロー画面遷移図
- 各種定義書
- テストに関する顧客要求
テストし易い単位から分析すれば、その単位(同じ粒度)でテスト対象を洗い出せるのではないか、ということに気づきました。
分析対象が何かというと、上記の整理した資料です。ですから、同じ分類や粒度が同じ分析対象を、一つずつ見ていけば良かったのです。
落ち着いて考えれば当たり前なことでしたが、情報を整理しないと、こういう混乱を招くという良い教訓になりました。
いきなりすべての資料(システム全体)に対して、分析をするのではなかったのです。分析対象が大きすぎますしね(^-^;
また、これに関連して気づいたのは、テストレベルが対象とする単位、粒度で考えてもよかったなということです。
V字モデルではテストをする順番は単体(単機能)テスト、統合(複数機能)テスト、システム(機能全体)テストですから。
しかし、私はやはりテストレベルから考えるより、分析対象を整理してから、その整理した情報ごとに分析をしていく方がしっくりくるようでした。
テスト設計技法が適用できるテストレベルはある程度示されていますが、テストレベルに対応するテストタイプは、テスト対象によるーとなってしまうと思うからです。
限定された業界や業務ならば、後者の考え方でテストタイプを限定しても良いかもしれません。
分析をすることのメリット
ただ、やはり分析をすることにはメリットがあります。
グループワークの発表や秋山さんの講義でも紹介されていましたが、どうやってテスト対象を導きだしたのか考え方を人に伝えられる、という点です。
「ちゃんとテストした?」と聞かれる人(私を含め)には、とても効果的だと思いました。
テスト分析の結果として、やるべきテストが決まる
昔「やるべきテストはテストレベルごとに決まっている」と私は思っていました。そういうものだと、思い込んでいました。
などなど
何をテストしたらいいのか分からないのは、テスト分析ができていないから
ここまでくると自分が何をすべきかは、もう分かります。
分析が上達すれば、テストするところはここだよって言えるようになるわけです。
ですから、私のテスト上達の鍵はテスト分析が上達することだと分かりました。
WACATEに参加した一番の収穫です。
振り返りしなかったら気づけなかったと思います。やっといてよかった。
分解
テスト分析の上達の為に大きなヒントになりそうな手法が、「分解」です。
秋山さんが講師として紹介してくださいました。
講義では要求が大きい場合、分解を利用して、具体的な要求を引き出していくと良いと教わりました。
USDM のような思考のフレームワークを使うと、上手に分解できるそうです。
- 時系列
- 構成
- 状態
- 共通部分
分解した結果を説明できるように一枚にまとめる
- 氏名
- 住所
成果物の確認
以上の分解によって成果物が出来上がります。
テスト分析の成果物は、テスト設計のインプットとなります。
あとはテスト分析の成果物に対して、テスト技法を適用してテストを設計(テストケースを作成)していくだけです。
ここまでで、テスト分析がテストの質を左右することが容易に分かりますね。
これをテスト計画やテスト者への指示に反映することで、チームとしてより良いテストが出来そうだと思いました。
チームの方への感謝
グループワークの最後に細川さんから、「テスト分析、テスト設計出来た?」という質問がありました。
私たちのチームは、テスト設計は「う~ん」でしたが、分析は「出来たと思う」人がほとんどでした。
成長しそうな予感の私のテスト
ドリル本を読み返して思い出したこと
同値クラス
先日、Twitterでだして下さったJSTQBの問題で、BMIの計算式がありました。
その時の論点は、式の結果の種類から同値クラス数を考えるものでした。
その時、身長が0の人はいないからどうするのかな?、マイナスのときはどう?と思いましたが、私は無効同値クラスとしてテストは必要だと思います。なので、同値クラスは5つかなーと思いました。
ドメイン分析テスト
ところで、これドメイン分析をすると、どんなテストケースが導けるでしょうか。
式には複数の変数があります。
その変数には同値クラスがあります。
それぞれの変数のon /off / inを考えると、効率良く同値クラスを検証するテストが出来そうですね。
身長(単位cm、有効桁数を小数点第一位まで)
on / off を考えると、off=0、on=0.1としましょう。in=160
体重(単位kg、有効桁数を小数点第一位まで)
on / off を考えると、off=0、on=0.1としましょう。in=60
これをもとに、ドメイン分析テストマトリクスを作ると、有効/無効同値クラスを効率良く作ることが出来ます。
計算式は、画面に出力する値を求めるとき、何らかの判定条件の基準を求めるときによく使われます。
私も実務では使ったことがありませんでした。総当たりテストをしてました(^-^;
読み返して理解できたので、使ってみようと思います。
私の考えるちゃんとしたテストに追加ですね。
私がいろいろな方から教わったり、勉強したことから考えた 「ちゃんとしたテスト」 について書きます
ちゃんとしたテストについて書かせて頂きます。
色々な意見があると思いますが、ぜひお聞かせください。
皆さんの足元に及ばないかもしれませんが、議論をさせてください。
↓ のつづき、書きます。
私の考える、ちゃんとしたテスト
単機能テスト
勉強して気づきましたが、自分が昔やっていたのは有則の単機能テストでした。
機能が仕様どおり実装されているかを確認していたからです。
なので仕様に定義されていない箇所のテストを考えられているか、以降は注意を払えるようになりました。
テストだけではなく、設計時にも。
テストの目的
仕様通りに実装されていることの確認です。
テスト設計の流れ
テスト対象の論理を把握する
どうテストを設計をするか、つまりテストケースを考えるかについてですが、その前に機能全体を把握している必要があると考えます。
知らない場合は、仕様書から把握するようにします。
ですがその当たり前がないケースも多々あります。
超短納期で設計と実装が並走する、意味がわからない状況もたまにはあります。
辛いですが、そんなときは息抜きを意識して、あきらめないようにしましょう。
これはテスト対象全体を見た時に、その一面だけを捉えてしまうことで、隠された項目や条件を漏らさないようにする為です。
例えば、画面の項目の表示、非表示を制御する設定ファイルの設定値などです。
ですから機能の外側を見て、入力、出力の数を見ます。
それぞれに複数入出力があれば、複数の論理(ロジック、筋道というと分かりやすいかも)があることが分かります。
HAYST 法において利用されるラルフチャートに近いかもしれません。
論理毎にテスト項目を探す
次に、論理一つずつに焦点を当て、その観点で機能の内側を見ていきます。
例えば、商品マスタ登録画面に、登録、削除、更新の機能があるなら、その3つの観点それぞれで見ていきます。
論理を一つづつ見ていくのは、経験的に処理毎に使われる項目が変わるかもしれないからです。
もしかしたら登録した商品コードはキーとして使われる為、更新できないかもしれません。
そうなると、更新時のテスト項目と、登録時の項目とは同じにはなりません。
ですから、私は単機能のテスト設計は論理ごとに行うと良いと考えました。
ところが、中には複雑な論理を1つの画面で実現する処理もあったりします。
そういう時は、テスト技法を活用すると良いです。
便利な技法
上記を支援する技法としては、論理を表現する、原因結果グラフ、CFD があります。
テスト技法としても紹介されるものですが、ここではツールとして紹介します。
私は、シンプルさと定義外の論理が見えてくることからCFDをプログラマさんとのテストケースレビューで使ったりします。
紙にちょろっと書く程度ですが、仕様を知らない場合、初めに論理の認識合わせをしてからでないとテストケースをしても効果がありません。
ですからレビューをするために書くのです。
本当は設計にこれら技法で表現された図があるといいと思っていますが、そうもいかないことが多いですから。
論理のテスト前に、単機能(単項目)のテスト
話を戻します。
論理を書いた後ですが、すぐには仕様としての論理の検証はしません。
なぜなら、その論理を構成する要素(単項目のチェック処理や、分岐条件の導出など)に誤りがあると、論理を作り直し(プログラム修正)になるからです。
プログラムを作り直したらテストはやり直しです。
私の場合は、ユニットテスト(≠単体テスト)を(書いてみたいけど)書いたことがない(書けない)ので、手作業でやり直しになります。
これは辛くて耐えがたい作業なので、ちゃんと単項目のテストをしようと考えました。
これはユニットテストの考え方に通じるものがあります。
アーキテクチャ構成要素の最小単位が検証され、品質が保証されていれば、そのアーキテクチャ構成要所の最小単位で構成される要素も同レベルの品質が保たれる可能性はあります。
この一方でアーキテクチャを構成する要素の中で一番数の多い最小単位の品質が悪いと、品質は一番低いものに足を引っ張られる特徴がありますので、システム全体の品質もその程度になってしまいます。
単機能テストのテスト技法
単機能をテストするときに確認するポイントは大きく2種類あります。
単項目の仕様(書式、値のチェック処理など)
単項目の仕様をテストする場合は、同値分割、境界値分析があります。
単項目の種類(文字、数値、日付、コードなど)に着目して、仕様から同値クラス、境界値を分析するのがポイントです。
また、テストを流す時はテスト対象外の項目はデフォルト値にすることがポイントです。
テストをしたい項目に他の項目の値が作用することを防ぐためです。
複数項目が関連するチェック処理
複数項目チェック処理をテストする場合は、デシジョンテーブルを作り、分岐条件を整理します。
上では原因結果グラフを論理を整理するツールとして紹介しましたが、ここではテスト技法として紹介します。
これを書けるようになるとCEGTestという、私がWACATEを知るきっかけをくれた方が作成してくださったツールが、圧縮済みのデシジョンテーブルを出力くれます。
私はこのことが便利なのは知っているのですが、僕はまだ原因結果グラフを書けないので、出来る範囲でデシジョンテーブルを作って圧縮せずに網羅的に整理してしまっています。
以上が単項目テストの設計手順です。
このように、ちゃんとした単項目テストを考えるようになりました。
皆さんの単機能テストはいかがでしょうか。
組合せテスト
単機能テストでは論理ごとにテストをしてきましたが、論理毎に見てもそれだけでは安心できません。
本来、論理毎に使われる内部的な変数を共有している可能性があるので、組合せテストをする必要があるのです。
テストの目的
論理内、論理間で使われる単項目を組合せた時に、仕様にない組合せで意図しない結果を引き起こさないかを確認することです。
組合せテスト設計技法
HAYST 法による直交表やオールペアがあります。
HAYST 法は実体験したことがないので、ペアワイズとどれだけバグ検出に差が出るのかは何とも言えませんが、テスト項目の導出だけならPairWiseを良く利用します。直交表を作る手順を整理できていないのと、PICTという便利なツールがある為です。
ですが、テスト設計の為には、HAYST 法 で紹介されているFV表、ラルフチャート、FL表の活用が有効だと考えています。
以上、単機能テスト、組合せテストは必ず単体テストのテストレベルで実践します。
組合せテスト2
私は組合せテストの考え方は、複数機能間のテストにおいても利用できると考えています。
余談
いきなり余談ですが、私はテスト設計について以下のような考えを持っています。
- 有効なテストケースを作成するテスト工程の一作業である
- テストケースの作成には、テスト技法、経験的に有効であると認められた知識としてのテストケースを取り入れることが、効率的で効果的なテストケース作成に有効である
私は様々なテスト技法の活用シーンを理解しておけば、「どのテストタイプ、どのテストレベルでどんなテストをしたらいいか」という疑問は少なくなるのではないか考えています。
「◯◯は死んだ」が今話題ですが、人(組織・チーム)を見て、技法(技術)を効果的に適用できるシーンから、適切なインテグレーション(適用、統合)の方法を考えればよいだけのことだと思うのです。
その人にとって見れば◯◯が合っていて、効果があればそれでよいのです。
機能間テストへの組合せテストの応用
ですから、複数機能間のテストでも、複数機能を一つの業務や作業のまとまり(サブシステム、機能よりも大きなまとまり)と考えて、テスト対象の因子をHAYST法で紹介されている6W2Hで分析していくと良いと思います。
例えば、「商品を出荷する」という作業のまとまりは、次の通りの作業で構成されていたとします。
・出荷指示を貰う
・出荷対象を在庫から引当する
・出荷対象をピッキングする
・出荷対象を検品、梱包する
(・出荷対象に宅配便伝票を貼る)
(・出荷対象を運送業者に渡す)
・出荷対象を出荷した記録を残す
※()は人手の作業
「出荷対象を検品、梱包をする」に改修が入った場合、「ピッキングしてきた出荷対象」が正しく検品できるか、が気になります。
また、「検品した出荷対象」に対して、「出荷した記録を残せるか」が気になります。
このように、作業を構成する機能間のインタフェースに不整合が無いことを確認できれば、既に単機能でのテストをしているので、上述した「商品を出荷する」の業務は滞りなく行えることを保証できます。
しかし、「ピッキングの商品リストを出力する作業の前に「商品名称の修正」をしたとしましょう。
普通に(?)設計されていれば、注文受付済みのトランザクションが、マスタを参照するような設計はしないですが、万が一設計か実装に欠陥があったとします。すると、業務担当者が商品名でピッキングしていたら、AでピッキングするはずだったのにBをピッキングすることになってしまいます。
このような一見関係のない機能間の処理によってデータの状態が変わってしまうような欠陥もあります。
組合せテストには、「有則/無則」という考え方があります。(禁則もありますが、理解が浅いので割愛します)
仕様の確認は「有則」のテストです。
仕様にない欠陥の発掘をするのが「無則」のテストです。
よって、無則のテストでは因子の1つにテスト対象の業務を構成する2機能(2水準)、もう一つの因子に水準に無関係な機能をN水準として、無則の組合せを考えます。
テスト対象と無関係な機能とは
これは、テスト対象機能で利用している情報を更新、削除する可能性のある機能と考えると良いです。
テスト対象機能において、SQL でマスタと結合してデータを取得してくることが出来る項目があったら、そのマスタを無関係な機能とすると良いです。
正常系の処理をしていた時は問題なく処理できていても、途中でその取り扱うデータの状態を変える可能性のある処理をしたときに思わぬ影響を及ぼすことがあります。
組合せテストではこのような利用方法がありますので、統合テストのテストレベルでも心がけるようにするようにしています。
状態遷移テスト
機能間の組合せという点では、システムやデータの状態についても、同様のことが考えられます。
状態遷移テストの目的
機能間の組合せテストでは、状態ではなくデータ不整合の有無に着目をしますが、
システムやデータには状態があり、ここで整理する状態遷移テストではそれら状態の正しさを確認します。
状態の特徴
データの状態は様々な処理の条件となる場合が多いです。
例えば、「ネットでの注文を確定するときの条件」です。
ネットでの注文には「品切れ」という商品の状態があります。
商品を選んでいた時は在庫があっても、注文確定時には商品が品切れになっている場合があります。
商品がカートに入っているからといって、品切れの商品を注文できてしまってはクレームに繋がります。
このように状態に着目してテストをするのが状態遷移テストです。
テスト技法
これらは、トリガーと状態の状態遷移表を書くとテストすべき仕様をきれいに整理できます。
また、状態遷移表を元に、遷移前、遷移後の状態の関係行列を作ると有則、無則の状態遷移をチェックできるのでおすすめです。
つまり、状態遷移表では仕様にあまり記述されない無則の部分の見落としを防ぐことが出来ます。
組合せテストと同様に、遷移が無いはずの処理を実行したときに、状態が遷移したりしないか注意することが出来るようになるので、よりバグが潜んでいそうなところをテスト出来ます。
更に、関係行列を2乗した1スイッチカバレッジ表まで作って、全パターンテストをすると内部の変数の故障などが見つかって良いです。
以前この関係のバグを見つけたときの例をツイートしたのですが、忘れてしまったので、思い出したらまた書きたいと思います。
シナリオテスト
シナリオテストも同じように、有則、無則の考え方を取り入れてテストをします。
テストの目的
システムを導入、改修して改善に取り組もうとした当初の目的を達成できているかの確認です。
改善するパターンをシナリオとして、そのシナリオをなぞります。
しかしなぞるだけでは仕様通りになっている事しか確認できません。ここでも有則・無則の考え方を適用します。
- 正常シナリオ
- 準正常シナリオ
- 異常シナリオ
この3点について考えてシナリオに対する考慮の抜け漏れを確認します。
また、シナリオを考えるときはHAYST 法の6W2Hで、考えると良いです。
(先日のリナさんと秋山さんのツイートを見て)ユースケーステストとは違うので要注意です。
シナリオテストはまだそれほどやり方を確立できていないので、この辺にしておきます。
ぜひ皆さんのシナリオテストを教えてください。
チームで一定のテストをすることのむずかしさ
この様に考えても、チームメンバーにその通りに実践してもらうのがなかなか難しいです。そもそも一定のテストをしたのは、テストケースの作成レベルにバラつきが多いからでした。
ですから、私の今の課題は、以上を実践して、メンバーからフィードバックをもらい、改善して、設計結果を全員でレビューしやすいフレームワークにすることです。
ちゃんとテストして嫌な思いをしたくないですから。
チームで一定のテストを実践、フィードバックを貰う為に取り組んだこと
実践してもらうにしてもある程度のフレームワークが必要です。
そこで、私はこの手順をテスト計画書の雛形として書き込みました。
私がいるチームでは作業をお願いする方が頻繁に入れ替わります。
その都度説明をするのは骨が折れます。ですから、計画書にして形式知にすることにしました。
実践したことの評価
しかしこれだけでは定性的な評価のままで、テスト設計の為のフレームワークのエコシステムは成立しません。
計画時に評価指標を定義して、計画時に想定した指標に対してレビュー時に評価しようと考えています。
陳腐化対策
さらに、仕事を一緒にしている人、WACATE のような勉強会で出会った方からの意見を頂いて的外れなことを言っていないか確認したいと思っています。
今日ここに来たのもそのためです。
まとめ
以上が、私が教科書を噛み砕いて、色んな方に教えて頂いて考えた、 今の実践する必要があると思っているちゃんとしたテストです。
もっとたくさんのことを学んできたはずなのですが、自分からアウトプットできないということは勉強したことが定着していない証拠だと思います。
これが私の実力だと真摯に受け止めて、これからは特に実践に励んでいきたいなと思います。
ぜひ皆さんのちゃんとしたテストについてもお聞かせください。
TwitterでもFacebookでも、カフェでもお酒を飲みながらでも、よろこんでお話をお聞きします。
私が「ちゃんとしたテスト」について書く前に、なぜちゃんとしたテストを考えるようになったかを書きます
はじめに
思うようにバグを見つけられず悶々とする日々
総当たりテストとの出会い
テストの自動化
テストの勉強を始めました
チョットデキル人に訊け!
そして「ちゃんとしたテスト」へつづく
How to run webdriver(Java) on Firefox 47.0 32bit
色々な文献を照会して試行錯誤した結果、
Firefox47.0をseleniumで動作させることが確認できました。
その方法を以下の通り共有します。
プログラム
prop.xml (プロパティファイル)
<entry key="geckoDriverPath">C:\Program Files (x86)\geckodriver-v0.8.0-win32\wires.exe</entry> <entry key="wiresPath">C:\Program Files (x86)\wires-v0.7.1-win32\wires.exe</entry> <entry key="32bitFFPath">C:\Program Files (x86)\Mozilla Firefox\firefox.exe</entry> <entry key="FFDevPath">C:\Program Files (x86)\Firefox Developer Edition\firefox.exe</entry> <entry key="NightlyPath">C:\Program Files (x86)\Nightly\firefox.exe</entry> <entry key="64bitFFPath">C:\Program Files\Mozilla Firefox\firefox.exe</entry>
Driver.java (Firefoxドライバを生成メソッドを定義したクラス)
public static WebDriver createFireFoxWebDriver() { // https://id:pw@url/でアクセス可能なFireFox用Profileを生成・ロードする ProfilesIni profile = new ProfilesIni(); FirefoxProfile myprofile = profile.getProfile("SeleniumProfile"); // geckoDriverではなく、wires.exeをwebdriver.gecko.driverとして指定する // System.setProperty("webdriver.gecko.driver", Props.hmProp.get("geckoDriverPath")); System.setProperty("webdriver.gecko.driver", Props.hmProp.get("wiresPath")); // プロファイルをセットする DesiredCapabilities capabilities = DesiredCapabilities.firefox(); capabilities.setCapability(FirefoxDriver.PROFILE, myprofile); capabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true); capabilities.setJavascriptEnabled(true); // marionetteをtrueにする capabilities.setCapability("marionette", true); // 32bit版FireFox v47.0を指定する capabilities.setCapability("binary", Props.hmProp.get("32bitFFPath")); // capabilities.setCapability("binary", Props.hmProp.get("FFDevPath")); // capabilities.setCapability("binary", Props.hmProp.get("NightlyPath")); // capabilities.setCapability("binary", Props.hmProp.get("64bitFFPath")); // (個人的な取り組み)でBasic認証を乗り越える設定を施す(プロファイルに設定しないときはコメントを外す→外してもダメだった。プロファイルに設定するのが無難) // capabilities.setCapability("browser.safebrowsing.malware.enabled", false); // capabilitiesにプロファイルを指定してドライバを生成する driver = new MarionetteDriver(capabilities); return driver; }
このような形で@Testを実行したところ、Firefox 47.0 32bit版(≠Developer Edition)を起動することが出来ました。
以下は起動したFirefoxのトラブルシューティング情報です。
アプリケーション基本情報
名前: Firefox バージョン: 47.0 ビルド ID: 20160604131506 更新チャンネル: release ユーザエージェント: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0 OS: Windows_NT 6.1 x86 マルチプロセスウィンドウ: 0/1 (無効) セーフモード: false
実行したテスト
試しに以下の簡単な処理を実行しました。実行できたseleniumメソッドの報告が目的なので、体裁は無視してます。
@BeforeMethod createFireFoxWebDriver(); //上記Driver.java記載の処理 driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); driver.get(url); // Basic認証が必要なサイトへリクエスト送信する driver.manage().window().maximize(); @Test PageObject TopPage = PageFactory.initElements(driver, PageObject.class); portalTopPage.web_element.click(); @AfterMethod driver.quit();
注意点
http://qiita.com/yssg/items/a054d67bc7c7fc39b276?utm_source=dlvr.it&utm_medium=twitter
こちらで紹介されていた「導入手順#2.GeckoDriverをwires.exe
にリネーム」が上記の場合、うまくいきませんでした。(Firefoxが起動しませんでした)
そこで「geckodriver-v0.8.0-win32」ではなく、「wires-v0.7.1-win32」を利用したところ、うまくいきました。
これは https://github.com/seleniumhq/selenium/issues/1431 ここで
@AutomatedTester(David Burnsさん)がコメントされていた「Was this using the latest wires release?」というコメントをヒントにしました。
上記に至るまでに試したこと。
- FirefoxプロファイルをロードせずにgeckoDriverでブラウザを起動する 非Basic認証サイトなら ◯
- geckoDriver+Nightlyを使う
- geckoDriver+Developer Editionを使う
Testを停止後、Firefoxが起動してテストケースが走るという意味不明な動作をしました。
No.2,3は47.0が起動してしまいました。
以上、少しでも参考になれば幸いです。
ReporterとListener
出来事
・テスト自動化ツールを改善した
特記事項
・成功/失敗したテストケースの判別
キーワード駆動テスト特有の課題である。
TestNGのテストランナーが同一のテストメソッドを実行するように実装している。(少なくとも私のツールの場合は)この為、テストケースを複数回実行するとどれが成功/失敗したのかがレポートでは分からなくなる。
この対策としてTestNGには、レポート機能を利用する。
・ReporterとListener
Reporterは@Testを付加したメソッド内で有効になる機能である。
@Test内で実装すると、「Reporter Output」をクリックしたときに右側に表示される「Reporter output for テストスイート」に@Testを付加したメソッドとReporter.log(String hogehoge)のhogehogeを出力することが出来る。
テストケース名の重複を許さないような実装にしておけば、どのテストケースが失敗したかはすぐに特定できるようになる。
Listenerに関しても同様のことが出来る。テスト起動時や終了時等、イベントを拾うメソッドをオーバーライドして利用する。
・ツールの設計の必要性
レポート機能は私がTestNGを使い始めたきっかけでもある。こんなところで生きてくるとは思わなかった。
どのようなツールが必要で、そのツールを構成するにはどんな要素が必要か、考える必要があると思う。
今回のツールの目的はマスタ登録後の登録ミスを検知する為のものである。
この流れの中で登場する人物は以下の通り
マスタを登録・修正する人
テスト設計する人
テスト実装する人
テスト実行する人
テスト結果を検査する人
FactoryとDataProvicerの違い
出来事
・チーズケーキフラペチーノを飲んだ。個人的にはうーんって感じ。
・リフレッシャーズ クールライムを飲んだ。うまい。
・いつもの湯葉の店で昼食を食べた。うまい。
・テストフレームワークを改善した。
複数のテストケースを別々のインスタンスで並列実行できるようにした。
反省
・コーディングに集中し過ぎて家庭での会話がそぞろ。気を付けないと(^_^;)
特記事項
・テストフレームワーク改善まとめ
どんなテストを実行するかによってアーキテクチャ要素(TestNG/JUnit)は変わる。
・DataProviderとFactoryの違い
DataProviderは、スクリプト駆動テストでは、同じテストスクリプトに様々なデータを投入してテストを実行する時に使う。キーワード駆動テストでは様々なテストデータのスクリプトデータを投入してテストを実行する。
単機能テストで威力を発揮すしそう。
Factoryは、Factoryオブジェクトがテストクラスをインスタンス化して、テストメソッドが実行される。同じテストクラスを別のインスタンスとして実行すると きに使う。
これでもDataProviderと同じことは実現できる。ただし同一テストクラスのインスタンスを使いまわすかどうかに違いがある。testng.xmlsのsuiteタグで、parallel="method"としてFactoryで実行すると一気にテストを実行できる。
・Factory実装のメリット
複数のテストを同時実行させる場合には大変便利な機能である。
例1)マルチブラウザテストのとき
同じテストデータで異なるブラウザテストを実施するケースがあるから、この時はFactoryで各々のブラウザでテストを実行するデータを投入してparallelにメソッドを実行すれば効率的である。
例2)単機能テストのとき
データプロバイダで同じ種類のブラウザを別インスタンスで起動すれば、失敗したテストが成功したテストの足を引っ張らなくて(影響しなくて)良さそうである。
合わせ技として、DataProviderが返したオブジェクトをFactoryアノテーションが受け取り、@Factoryがついたコンストラクタがそれを引数としてとりながらFactoryクラスによってインスタンス化されテストメソッドを実行させるというやり方もある。
参考 TestNG – @Factory Annotation Tutorial – HowToDoInJava
http://testng.org/doc/documentation-main.html#factories
・Factory実装のデメリット
DataProviderからテストメソッドにデータを渡すと、どんなデータが渡されたかが分かる。 DataProviderからテストクラスのコンストラクタにFactoryアノテーション経由で渡すと、どのケースによって対象のテストが実行されたかが分からない。
キーワードテストではテスト実行メソッドは一つだからどのケースが失敗しているのかが補足できないとテストの再現が出来ない。
Listeners/Reportsを利用して改善が必要
以上