はじめに
Javaの開発では、多くのプロジェクトでオープンソースのテスティングフレームワーク「JUnit」が使われています。テスティングフレームワークを使った単体テストのメリットは、テストコードを一度作成することで同じ条件のテストを繰り返し実行でき、結果の確認を自動で行えることです。
「品質をもっと上げたい」「開発工数を減らしたい」といった期待を持ち、多くの開発者は単体テストや単体テストの自動化に取り組みます。しかし実際に導入し、運用してみると、「予想以上に工数がかかっている、思ったほど効果が出ない」または「運用しているが非常に苦労している、ちっとも楽にならない」といったことに陥りがちです。
ここでは、なぜそのようなことになるのか、特にありがちな3つの失敗例とその対策を紹介します。
- 【失敗例1】単体テストを導入したら工数が増大した
- 【失敗例2】単体テストを実施していたが、メンテナンスコストが増大し、やらなくなった
- 【失敗例3】ソースコードカバレッジの罠にハマる
本稿ではそれぞれの失敗例に対する一般的な対策を紹介しますが、それだけでは劇的な改善を望むことはできません。
そこで、失敗例の対策を加速させるために、商用ツールであるParasoft社製「Jtest」の「単体テストアシスタント(Unit Test Assistant)」を使う方法も併せて紹介します。
Parasoft社の調査によると、単体テストアシスタントを使用している顧客からのデータでは、単体テストの労力が50%も削減されているとのことです。また、私たちの独自の検証では、単体テストに慣れていない新人開発者において、実際に工数を約33%減らすことができました。これは衝撃的な数字です。
どうすれば単体テストで期待通りの効果が出せるのか、失敗例と対策から見ていきましょう。
【失敗例1】単体テストを導入したら工数が増大した
単体テストを実施するためにはコストがかかる、ということはよく知られていますが、予想以上に工数がかかり過ぎて社内に普及しなかったり、手間がかかり過ぎて開発者の負担が大きくなってしまったりすることはないでしょうか? また、単体テストをすでに運用している場合でも負担を減らしたい、といった話もよく聞きます。
では、なぜ工数が増大するのでしょうか?
【原因】1.実装コストがかかる
単体テストはプロダクションコードと同じ、またはそれ以上のテストコードの実装が必要であり、多くの時間がかかります。また、テストもプログラムなので、意図した通りにテストが動作するかを確認するためデバッグも行う必要があり、工数がかさんでいきます。
【原因】2.学習コストがかかる
新人や経験の浅い開発者がプロジェクトに参画した場合、JUnitの実装やテストの方法を学習する必要があります。また、Javaの開発では当たり前のようにアプリケーション開発フレームワーク(Springなど)を使用しますが、そのテストはフレームワーク独自の手続きが必要な場合もあるため、学習が必要です。
それぞれへの対策としては、以下が挙げられます。
【対策】1.実装コストがかかる
一般的な対策
テストコードの記述にはどうしても時間がかかります。そこで、プロダクションコードをテストしやすいコードにすることで実装にかかる時間を削減します。単体テストを考慮していないコードは複雑になりがちで、テストの作成が難しく、単体テストの実装に時間がかかります。テストを見越した設計や実装を行うことで、シンプルな設計、実装になり、テストの作成にかかる時間を削減します。
さらにJtestによる対策「テンプレート機能を使って実装コストを削減」
Jtestのテンプレート自動生成機能を利用することで、開発者の手作業を減らし、デバッグも効率良くできるようになります。Jtestでは以下のようにテストを作成します。
(1)テストケースの作成
クリックひとつでテストケースのテンプレートを作成します。テストケースのスケルトンだけでなく、値の設定が必要なパラメータ定義も作成します。さらに、CSVからテストデータを流し込むパラメータライズのテンプレートも作成可能です。
(2)アサートのテンプレート作成
テスト実行後の結果を期待値に設定することができます。テスト実行後、期待した結果が得られたことを確認し、クリックひとつでアサートを作成します。
(3)テストのデバッグ
期待通りの結果にならなかった場合、ステップ実行やログ出力を追加して動作の確認を行います。Jtestではテストの実行を監視し、実行時の処理経路(スタックトレース)やメソッドの戻り値、引数の値を記録します。そのため、プロダクションコードのどのコードが実行され、どのように値が変化し、処理されたのかを瞬時に確認し、デバッグ作業の手間を削減します。
【対策】2.学習コストがかかる
一般的な対策
経験の少ない開発者に対しては、テストしやすいクラスから経験を積んでいきます。例えば、依存関係の少ないユーティリティクラスや、処理が複雑ではないPOJOなどを選んでテストの実装方法や進め方に慣れてもらいます。学習コストはかかりますが、簡単なところから徐々に範囲を広げていくことで、失敗を防ぎます。
さらにJtestによる対策「テンプレートを自動生成することで学習コストを削減」
Jtestではテストケース、アサートだけではなく、モックやフレームワークなどさまざまなテンプレートを自動で作成することで、単体テストの学習コストを削減します。
(1)モックテンプレートの作成
モックの複雑な呼び出し手順を覚える、振る舞いを理解するには経験が必要です。Jtestではモックのテンプレートの作成や、モックを監視して依存関係を自動で検出することで、間違えやすい手作業のコーディングを削減します。
(2)Springテストケースのテンプレートの作成
Springは独自のテストフレームワークを提供しており、効率良くテストが実施できますが、その使い方を学習する必要があります。Jtestを使うと、Spring特有の手続きが記述されたテンプレートが作成されるため、新たに学習する時間を削減することができます。
Jtestの無料体験版を入手!
Jtestの無料体験版を配布しております。以下のリンクからダウンロード可能です。