連載
» 2009年09月14日 00時00分 公開

PHP開発者のためのテストのすゝめ(1):ユニットテストはなぜ必要なの? (1/2)

開発の全工程の中で、あまり人気がないのがテスト工程だ。ソフトウェアの品質を証明するためのテストは、なぜ低く見られてしまうのか(編集部)

[繁田卓二,株式会社 qnote]

そもそもテストはなぜ実施するの?

 皆さんはテストと聞いてどういったイメージをお持ちでしょうか。

 「面倒くさい」「プログラマの仕事じゃない」「納期直前に徹夜でするもの」「そもそもしない」……。

 残念ながら筆者の周りにいる開発者に聞いてみても、あまり人気のある工程とはいえないようです。

 さて、本連載で扱うテストとは、もちろん学期末の終わりに実施するような人の知識、習熟度を試すテストではありません。ソフトウェア開発におけるテスト、つまり「ソフトウェアの品質を証明するためのテスト」のことです。自分たちが作り上げたソフトウェアに対して自らテストし品質を評価する工程、そして、テスト結果は常に100点である必要があるという半ば自己満足的な性質を持つ試験のことです。

 しかし、テストはソフトウェアに限らず、自動車でも家電製品でも性能試験は品質を向上するためにも不可欠な工程です。誰しも試運転していない製品を買いたくはありません。学期末テストとは違い、点数(結果)が重要なのではなく、テストを実施すること、またその過程こそが重要なのです。

ユニットテストは何を行っているの?

 一般的にテストといってもさまざまな種類があります。モジュール単位で試験を行う単体テスト、モジュールを組み合わせて試験を行う結合テスト、高負荷時の耐久性を調べる負荷テスト、顧客により行われる受け入れテストなどが挙げられます。

 Webアプリケーション開発においては、単体テストで関数やクラスメソッドをテストし、結合テストでWebブラウザからの操作をテストするのが一般的です。前者の単体テストをユニットテストと呼び、最近ではどの言語でもユニットテストを自動化するツールやテスティングフレームワークが登場しています。PHPでは、PHPUnitSimpleTestなどがよく使われています。

 ユニットテストは関数やクラスメソッドを最小処理単位として扱い、引数を処理した「結果」と、想定される「期待値」の2つの関係を比較するものです。また、ユニットテストツールはこれらの比較を自動化するものです。

 ツールと聞くとGUIが用意されて、クリック操作だけですべてがテストできるような夢のアプリケーションを想像しがちですがそうではありません。比較ロジック自体は開発者の手によりコードを記述しなければなりません。

 ユニットテストツールはそのコード化されたテストを自動実行するためのものです。このコード化されたテストをテストケースと呼びます。なぜわざわざテストをコード化する必要があるかというと答えは簡単で、プログラム言語で記述された関数やメソッドは同じプログラム言語でなければ実行ができないからです。

 要するに、関数やメソッドを実際にコールし、期待どおりの値が返されるかというロジックをコードで記述するのです。関数やメソッドを作成する際に、期待どおりの結果が返るかどうかを試すために一時的にprint文やvar_dump()関数を使って標準出力に吐き出すことはないでしょうか。ユニットテストではこういった処理の試運転をテストケースとして記述しておき、関数やメソッドを徹底的に試運転するのです。

 ユニットテストツールでは、アサーションという比較のためのメソッドが多数用意されています。以下はPHPUnit3でのテストケースの例です。

// $varがTRUEであるかどうかのテスト
$this->assertTrue($var);
// $varが、期待値$expectと等しいかどうかのテスト
$this->assertEquals($expect, $var);
// 期待値$expectが、変数$varより小さいかどうかのテスト
$this->assertLessThan($expect, $var);
// $finenameのパスにファイルが存在するかどうかのテスト
$this->assertFileExists($finename);

ユニットテストツールを使用するメリット

 ユニットテストツールのメリットにはさまざまな側面があります。1つはテスト自体をコード化することでテストの実施が自動化できること。もう1つは、テストケースを残すことにより同じ水準でのテストが再実行が可能なことです。

 大切なのは、テスト結果を残すのではなく、テスト自体を残すということです。過去のテスト結果などはプログラムが少しでも変更されれば意味を成しません。しかし、テストケースが残っていれば、ユニットテストツールでいつでも再テスト結果を得ることができます。

 通常、プログラムに変更があった場合は、予知できない影響範囲を検出するために、関係のなさそうな機能も含め、すべてのテストを実施し直すという非常に面倒なリグレッションテスト(回帰テスト)が必要ですが、これもテストケースが残っていれば、まったく同じ精度で再テストできるのです。

 もしテストが残っていなければどうなるでしょう。開発中は一時的なテストをしながらコードを書き、動作に自信があったかもしれません。仮にその処理が完璧なものであったとしても、数カ月後、数年後に仕様変更が発生した場合、その自信は残っているでしょうか。もう一度テストを実施しようとして同じテストを再現できるでしょうか。

 「私は記憶力が良いので何年も忘れない」という人がいたとしても、数年後の仕様変更作業をその人が実施するとは限りません。別の人が引き継いでも同じ水準でテストを実施し、同じ品質を保たなければいけないのです。

       1|2 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。