テスト設計 第一部 ~ユニットテスト編~

テスト設計 第一部 ~ユニットテスト編~

どうも、今年の夏はユニットテスト漬けだった大友です。

というわけで、「ホワイトボックス」と「ブラックボックス」の二つの視点から、ユニットテストの作り方を考察していきたいと思います。

前回、続編を望むコメントは特に無かった模様ですが。。。
この程度、想定の範囲内だよっ!(切ない)

前回のおさらい

前回の記事で「ホワイトボックス」と「ブラックボックス」の利点欠点を取り上げました。

ホワイトボックステストとは、内部の処理をすべて網羅することで、「誤字や変数参照ミス」などのケアレスミスや「正しくキャッチされていないエラー処理」などの異常系が正しく動くかどうかの問題を発見するためのテストのことです。
そのため処理完了の結果、ストアされる値が正しいかどうか、戻り値が正しい値かどうか、という部分は感知できません。

逆にブラックボックステストは処理の中身や流れは見ず、入力値に対する出力結果が正しいかどうかのみを確認します。

アチラを立てればコチラが立たず。
さて、一体どうやってテストを作っていけばいいでしょうか?

ブラックボックスの視点からテストを作る

ではまず、手始めに「完成した処理を実際に動かしたら、想定した答えがちゃんと返ってくるか?」ということを確認しましょう。

超シンプルな例を一つ。
ブール値を引数に、各々対応した数値を返す処理があったとします。

この場合、以下のような感じで関数に引数を渡してあげれば、result変数にそれぞれ結果が返ってきますね。

後はその返ってきた結果が「1」か「0」か「null」か、とそれぞれチェックしてあげればいいですね。
ついでに判定した結果をカウントしながらテキストログにでも吐き出せば、テスト何件中のうち何件OKで何件NGなのか、といったデータを出すこともできます。

ホワイトボックスの視点からテストを見直す

さて、次に「作ったテストがちゃんとロジックを網羅しているか?」ということを確認します。
「処理がすべて網羅されていることを確認する」ために必要となるのが、「カバレッジ計測」というものです。
では、先ほどと同じ関数をサンプルとします。

このとき、テストコードを書いた人が「ブール値はtrueとfalseだけだから、この2パターンでいいな!」と考えて、以下のような感じのコードを書いたとします。

では、抜け漏れがあることに気付かぬままテストコードを回したらどうなるでしょうか。

  =テストが通ったロジック

「カバレッジ計測」だとこうなります。
テスト実行によって、通っていない処理がどこか分かるので、上の例では「例外処理に関してはチェックできていませんよー」ということが分かるわけですね。

ただこの「カバレッジ計測」、100%クリアならオールオッケーかというと、必ずしもそうではないのです。
その辺りは『カバレッジ計測編』と銘打って一本記事を書けそうなレベルになってしまいますので、また次の機会にでも。

実際にテストしてみた話

さて、ここまでは理論のお話。
今回、私がテストしたシステムは、弊社がご提供させていただいているとあるブラウザサービスのJavaScriptで構成されたフロント機能(ブラウザに反映される部分)になります。

なお、テストコードの作成には「SeleniumWebDriver」を使用しました。
コイツは本来、マウスのクリック・スクロール・カーソル移動やキーボード入力といった、人間の操作をエミュレートするコードを書けるのが目玉機能なのですが、今回はexecuteScriptというAPIを使って「処理を行うJavascriptの関数を直接実行する」というコードをツラツラと書いていきました。

つまり、ブラウザのコンソールに手入力でJavaScriptのAPIを打って毎回確認していたものを、Selenium側で書き溜めておいて一括で実行、かつ、何度でも確認できるようにしたわけです。

利点としてはブラックボックスのテストコードを順次、書いては実行、書いては実行を繰り返し、モジュールが完成するたびに結合テストを回すような感覚で単体テストが実施できたことでしょうか。

モジュール1が完成する→テストコード1を作る→テスト1実施→OK!
モジュール2が完成する→テストコード2を作る→テスト1・2実施→OK!
モジュール3が完成する→テストコード3を作る→テスト1・2・3実施→OK!
上記のような感じです。
当たり前ですが、一度作ってしまえば何回使ってもタダですからね。

欠点を強いて言えうのであれば、設計の見直しや手戻りがある度にテストコードを修正しなければならないため、方針がある程度固まるまでの最初の数週間は非常に手が掛かったということでしょうか。

最初が大変だったため、「既にこんなに大変なのに、ちゃんと完成するのだろうか……」と不安に感じることもありました。
そこだけはテストをスクリプト化するという自分の方針を信じ、「後でラクをするために、今は苦労を前借りしているのだ…」と自分に言い聞かせる必要がありました。
そして、実際そうでした。

いつかはSeleniumを理解していない人でも自動テストが回せるように

「テストしたいコード」と「想定している結果」の情報さえあれば、いつでも誰でもテストが実行できる、というところまで来れば、もう自動化の仕組みとしてはアウトプット完了したも同然って感じがしますよね。

例えば、Selenium内にテストコードを直接書かず、処理自体はJSファイルに書き溜めて、それをSelenium内でファイル読込→文字列→処理するようにすれば、Seleniumを使ったことがない人でもテストしたいJavaScriptを一括実行、実行結果の参照ができるようになりますね。

発展形として、「xls」や「csv」でテストコード&想定する実行結果をセットで記入して、それを取り込んで結果をログファイルで返す形にすれば、「検証シートを作るだけでテストと結果のまとめはPCがやってくれる」ようになります。

夢がありますね!…まぁ、言うだけですぐできるほど、簡単な話ではないんですけども。

テスト自動化・効率化についての話は、別の部で続きを書くことに致しましょう。
これにて第一部、完!

コメント