
プログラマーがソフトウェアを作るとして、そのソフトウェアが正しく動くかどうかはだれが確認するのでしょう?職種としてよく目にとまるのは「テストエンジニア」と呼ばれる人たちになります。
テストエンジニアについてはこちらの記事も参照してみてください。

確かにそうかもしれません。ですが、プログラマーがテストプログラムを書けるとさまざまな良いことがあります。最初の疑問に答えるべく、その良い面を説明していきたいと思います。
テストプログラムとは?
テストプログラムとはそもそも何か?というと、プログラムをテストするためのプログラムです。テストコードと表現される場合もあります。
「仕様」と「テスト」
プログラムを作るとき、そのプログラムがどんな風に動くべきか?が書かれたドキュメントを「仕様書」と言います。プログラマーはその内容の通りに動くプログラムを作ります。
練習問題などでよく出てくるFizzBuzzゲームで例えると、以下が「仕様」になります。
- 1から100までの数字のうち、好きな数字を入力する
- 入力された数字が3の倍数のとき「Fizz」と出力
- 入力された数字が5の倍数のとき「Buzz」と出力
- 入力された数字が3の倍数でもあり5の倍数でもあるときは「FizzBuzz」と出力
「テスト」はその仕様どおりに動いているかを確認することで、以下がテストの例になります。
- 4を入力したら何もでない
- 5を入力したら「Buzz」と出力される
- 30を入力したら「FizzBuzz」と出力される
テストプログラムは「作ったプログラムを呼び出し、5という数字をわたしたら、Buzzと出力されるか」を○×で調べるプログラムというイメージです。
テストにも段階がある
一言でテストといっても、先ほどの例のように、シンプルな一つの機能の動作を確認するものから、「Youtubeの動画がブラウザから正しくアップロードできるか」といった複雑なものまであります。
一般的には以下の段階にわけて、順番に実施されていることが多いと思います。
- 単体テスト
- プログラム内の1機能またはそのプログラムだけで動く機能を確認するテスト
- 結合テスト
- プログラム同士が連携して動くような動作を確認するテスト
- システムテスト
- さらに他のシステムと連携する機能の動作を確認したり、プログラムを動かす環境の動作も含めて確認するテスト
はじめの一歩からということと、プログラムによるテストは段階が進むほど難しくなるので、この記事では単体テストにおけるテストプログラムについて説明していきます。
単体テストにおけるテストプログラム作成のコツ
テストプログラムはプログラムの動作を確認するためのものであるため、テストプログラム自体が正しく動かないと、何がおかしいのかわからなくなってしまいます。
ですので、テストプログラムはわかりやすい名前をつけて、余計な動作をしない単位で作るのがコツです。先ほどのFizzBuzzプログラムをテストする場合の良い例と良くない例を挙げてみます。
- テストプログラム名「4の確認」: プログラムに4を入力してなにも出力されたかったら○にする
- テストプログラム名「5の確認」: プログラムに5を入力してBuzzが出力されたら○にする
- テストプログラム名「6の確認」: プログラムに6を入力してFizzが出力されたら○にする
- テストプログラム名「15の確認」: プログラムに15を入力してFizzBuzzが出力されたら○にする
- テストプログラム名「101の確認」: プログラムに101を入力してエラーになったら○にする
- テストプログラム名「FizzBuzzの確認」: 入力する数を1から101までループさせてプログラムを呼び出し、正しい結果が帰ってきた場合は○を出力し、正しい結果が帰ってこなかったら×を出力する。
良い例では、もしどこかのテストプログラムで×が出た場合、どの「仕様」が正しくプログラミングされていないかがすぐにわかります。そしてテストプログラム自体も単純な処理になるため、バグが発生しにくくなります。
それと比べて良くない例では、1回のテストプログラム実行で終わるので、一見効率が良いように見えますが、次のような問題があります。
- テストプログラムの処理が複雑なので、そちらにバグを作り込む可能性が高い
- ×が出力された場合、どこの処理が悪かったのか、すぐにわからない
- 何度も同じ条件を確かめているので無駄なテストが多い
2つの例をみてどう感じましたでしょうか?テストプログラムは何か問題が起きたときに、すぐ「どこの」「どんな処理が」悪かったのかがわかるように作るのがポイントなので、最初は面倒に思うかもしれませんが、良い例のように小さくテストしたいポイントに絞ってたくさん作るほうが良いのです。
テストプログラムがあることのメリット・デメリット
メリット
「デグレーション」を防げる
プログラムもテストプログラムも書いたとおりにしか動きません。プログラムを修正しても、テストプログラムは何度でも同じように「仕様」を確認してくれるため、以前と違う処理にしてしまっていないか?がすぐにわかります。
新しい機能を追加したりしたときに、もともと正しく動いていた処理が違う結果を返してしまう、といったバグを作り込んでしまうことを「デグレーション」と言います。テストプログラムがあることで、この「やっちまった!」をいつでもチェックすることができるので、プログラマーにとってテストプログラムは強い味方になります。
「仕事」として引き継ぎやすくなる
もともと自分がイチから作ったプログラムなら「中身もわかってるし、大丈夫」と思えるかもしれませんが、ゆくゆくは人の作ったプログラムの面倒をみることもあるかもしれません。そんなとき、テストプログラムと一緒に引き継いでもらえれば確認も簡単になります。
そのときテストプログラムの名前や説明が「××の〇〇をチェックしている」ということがわかるようになっていると、いざ問題が発生したときに自分が作ったプログラムでなくとも対応がしやすくなると思います。
自動化できる
テストプログラムを書く最大のメリットではないかと思いますが、テストプログラムも立派なプログラムなので自動的に動かすことが可能です。プログラミングを終えて、ちょっとコーヒーを・・・という間に、テストプログラムを全部自動で走らせておけば心に余裕も生まれますね。
デメリット
テストプログラムを正しく作れないと意味がなくなる
当たり前なのですが、テストプログラムが正しい結果を出せないと、意味がなくなってしまいます。また、テストプログラムがテストしたいプログラムに渡す引数の意味も重要になります。
ただ、考え方としてはもともとプログラムで実現したい「仕様」があるわけですから、仕様どおりに動くかを確認できるような実装ができていれば問題ありません。
単純にプログラミング作業が増える
こればっかりは致し方ないところですが、プログラムの倍かそれ以上プログラミング作業をしなければなりません。ですが、いずれ出来たものを確認する作業は必要なので、プログラムを作っているうちに一緒にテストプログラムも作ってしまったほうが、後でテストケースを作るより間違いは少なくなると思います。
プログラムの仕様が変わるとテストプログラムも修正が必要になる
プログラムも修正したら毎回テストプログラムも修正が必要なのでは?と思うかもしれませんが、修正しなければならないケースは、仕様が変わったり、追加になったり、削除されたりといったテストしたい内容が変わったときだけです。
毎回全部を書き直す必要はありませんが、書き直す必要のないところと書き直すべきところを正しく把握して対応できるようにしておくことが大事です。
まとめ
この記事では、単体テストという段階においてテストプログラムがどんな役割を果たし、どのようなメリット・デメリットをもたらすかについて、簡単ですが書かせていただきました。
プログラマーがテストプログラムを準備することで、自分の作業の効率や、開発全体の手戻りのリスクを減らすことにもつながるのです。そういった意味で、アジャイル開発のスタイルをとっているチームや会社にとっては、当然のようにテストプログラムを書くことを求められる可能性も否定できません。
そんな状況におかれたとき、仕様にもとづいた良いテストプログラムが書けるようになるために、この記事が少しでもお役にたてるのであれば幸いです。
冒頭の質問に「テストエンジニアに任せたらよいのでは?」というコメント例を書かせていただきました。ですが、本来テストエンジニアが考えるテストケースは、慣れたプログラマーやシステムの仕様を考えた人でさえ見落としてしまいそうな、利用者目線・システム目線での異常なケースを見つけることにその能力が発揮されたほうが良い、ということも頭の片隅に置いておいていただければと思います。