テスト、という言葉はよく聞くし、何となくのニュアンスは分かるのだが、実際のところは理解していない。
だから当然、実践もしていない。
テストとは何か。
どんなメリットがあり、なぜ推奨されているのか。
自分もやるべきなのか。
実際にやるためには、具体的にどうすればいいのか。
そういったことを知りたい。
テストとは何か
テストには、単体テストと結合テストの二つがある。
結合テストは、ソフトウェア全体の挙動をテストする。
それに対して単体テストは、関数単体をテストする。
特に注釈なく「テスト」と書かれている場合、単体テストを指していることが多い印象がある。
単体テストについて。ユニットテストと呼ばれることもある。
関数の入力値と出力値が仕様通りか、意図したものかをチェックすること。言い換えると、入力値と出力値を持たない関数は、テストのしようがない。
まあ、テストが必要な関数で、入力値も出力値も持たせられない、というケースはないような気がするが。
JavaScriptにおいては、単体テストのためのツールとして、mocha、chai、などがあるらしい。
テスト駆動開発(TDD)
プログラムを実装する前にまずテストを書く、という開発手法のことを、テスト駆動開発、またはTDD(Test Driven Development)と呼ぶ。
参考:テスト駆動開発へようこそ
テスト駆動開発のメリット
ではなぜ、先にテストを書くべきなのか。時間の無駄ではないのか。最初から実装してしまったほうが速いのではないか。
テストのメリットについては、この記事が分かりやすかった。
テスト駆動開発とは何か、それを気に入っているのは何故か、あなたも使うべきなのは何故か
テストがないと、正しく動いているかどうかを、手動で確認しないといけない。
作り始めはまだいいが、機能が増えれば増えるほど、確認すべき事柄は増えていく。
しかも、異なる機能同士が衝突していないかも、確認しないといけない。
新しい機能を実装する度に、その機能に加えて、それまでに実装した機能を全てテストしなければいけないということでしょうか?
そう、その通りなのです。TDDを利用しないプロジェクトではリグレッションが生じやすくなるため、新しいバージョンをリリースする度に全ての機能を手動でテストすることとなって、恐ろしくコストがかさみます。
リグレッションとは、ソフトウェア開発の用語で、旧バージョンで正常に動作していた機能に、後続のバージョンでバグが発生することをいいます。
今の私はまさにこういう状態であり、本当にバカバカしい。
リグレッションを恐れるがゆえに、何度も念入りに手動でテストしている。とても効率が悪いと自分でも思う。
自動テストを利用するテスト駆動開発を採用すれば、このようなことをしなくて済むのだという。
ということは、テスト駆動開発というのは、自動的にテストが行われるような環境を作っていく、そういう開発手法のことなのだろうか?
もちろん、テストを書きながら開発していく手法は、テストを書かない場合に比べて、時間がかかる。
だが開発がある程度以上の規模になった段階で、それは十分にペイする。
自動テストをしていなかったら、手動のテストにかなり手間がかかるからだ。規模が大きくなるほど、そうだ。
それに当然、テストをしていたほうが、バグは少なくなる。
しかも、貴重な労力や時間を、バグの修正ではなく、新しい機能の追加などの前向きなことに使えるというメリットもある。
テストカバレッジ
テストした(しようとしている)部分が占める割合のことを、テストカバレッジという。一般に、パーセンテージで表現される。
テストカバレッジには、いくつかの種類がある。
コード全体に対してどれくらいテストしたかを示すコードカバレッジ、仕様書(要件)に対するテスト比を示す仕様カバレッジ(要件カバレッジ)、など。
一言にテストするといっても、何を、どのようにテストするのかについては、様々な考え方がある。
そしてそれは、プロジェクト毎に異なるだろう。プロジェクトの特性に見合った、テストの方針を立てる。
そして、その方針に沿ったテストがどれくらい実施されているかを計測するために、テストカバレッジがある。
そのため、テストカバレッジにも様々なものがあり、適切なテストカバレッジを採用することが重要となる。