Headline About TechLog Download Java VBA Link


October 18, 2007. Thursday.

JUnitとは

JUnitはJavaプロジェクトにおける単体テスト、すなわちUnit testを効率化するためのフリーのツールです。テストを自動化し、結果のビジュアライズ化を計ることで、単体テストのやり直しのコストを下げ、XP (eXtreme Program)に代表される、Test Firstなプロジェクトにおいては必須のツールの一つです。JUnitはその名の通り、Java専用ツールですが、同様のコンセプトでCUnitやPerlUnitなども公開されています。興味のある方は探してみてください。

JUnitはコマンドラインから実行が可能で、独自GUIによる結果が可能ですが、最新のEclipseには標準でインストールされているため、Eclipseから利用したほうが便利です。そのため、当サイトの記事中では、Eclipseからの利用を前提に説明を行います。とはいえ、基本的な考え方は、Eclipse以外の開発環境から利用しても共通ですのでご心配なく。また、この機会にこちらを参照し、Eclipseの導入も検討してみるのも良いかもしれません。




JUnitによるテストコードの自動生成

さて、細かい説明はさておき、とにかく動かしてみないとイメージがつかないと思いますので、まずは最初にJUnitの自動生成機能を利用してテストクラスの作成を行ってみましょう。その前に、テストされるクラスを準備しましょう。こんなクラスを作ってみました。

package net.sdls.barista.tech.utest;

public class Dog {
  /** 実行すると"Bow wow!"と吠えます */
  public static String howl() {
    return "Bow wow!";
  }
}

犬を表現するクラス、Dog Classです。staicメソッドhowl()を実装し、実行すると"Bow wow!"という鳴き声をリターンします。さて、それではこのクラスをテストするためのテストクラスを作成してみましょう。

まずは、先ほど作成したDogクラスと同じフォルダ上で[右クリック]→[新規]→[JUnitテスト・ケース]と選択し、右のようなダイアログを開きます。[テスト対象のクラス]の右の[参照]を押下するとさらに、子ダイアログが表示されますので、上部テキスト入力欄にDogと入力し、下のリストから先ほどのDogクラスを選んでOKを押下します。名前欄にDogTestと入力し、[次へ]を押下したら、テストメソッド選択画面でメソッドhowl()にチェックを入れ[終了]を押下してください。これでJUnitテストケースの完成です。以下のようなソースが自動生成されるはずです。なお、このサンプルはJUnit 3.8.1を選択して作成しています。バージョンの違いに関する説明は後の章で改めて行う予定です。


package net.sdls.barista.tech.utest;
import junit.framework.TestCase;

public class DogTest extends TestCase {
  public void testHowl() {
    fail("まだ実装されていません。");
  }
}

※JUnit 3.8.1へビルドパスが足りないというエラーがダイアログ下部に表示されることがあります。その場合、「ここをクリック」という指示に従えば解決します。




JUnitによる単体テストの実行

では次に、実際にJUnitを使ってテストコードを実行してみましょう。先ほど作成したDogTestクラスのソースコード上で、[右クリック]→[実行]→[JUnitテスト]と選択します。すると、テストが実行され、右のようにテストの結果画面が表示されます。

画面の上部はテスト結果を表示しています。いくつのテストを実行し、何個のエラーが派生したかが数値化され、結果が棒グラフで示されます。ただし、棒グラフと言ってもこのグラフ、仮にテストが9/10成功しても赤いままです。全部の試験が通らない限り緑にはなりません。その仕様からわかるとおり、このテストは「最終的に通るようにしよう」という物ではありません。「常に100のテストが通る状態をキープする」為の物なのです。画面中央には試験ごとの結果がツリー表示されます。。

画面の下半分にはエラーの理由と発生場所が表示されます。サンプル中ではfailメソッドを呼び出すことで、わざと失敗させているので、failメソッドの引数が理由として表示されています。他にも様々な方法で結果の表示が可能ですが、詳細については以降の章で取り上げる予定です。




テストコードの編集

失敗例ばかり見ていてもつまらないので、テストコードを編集して、プログラムが正しく動作した場合には、緑のバーが表示されるようにしましょう。テストするhowlクラスは、正常動作すると、"Bow wow!"という文字列を返す予定ですから、戻り値が"Bow wow!"で無かったときにだけエラーとなるようにすればいいわけです。先ほどのテストメソッドの中身を以下のように編集しました。


  public void testHowl() {
    Sting result = Dog.howl();
    if (!"Bow wow!".equals(result)) {
      fail(result + " != Bow wow!" );
    }
  }

今度は緑のバーが表示されました。非常に気持ちがよいですね。この気持ちよさこそがTest firstへの第一歩となります。なお、上記のテストコードを !result.equals("〜") と書かなかった理由がわからなかった人はこちらをご参照下さい。




安全にリファクタリングを実現する

さて、先ほどまでの手順でテストクラスを作成しました。このようなテストクラスを作っておくと、気軽にリファクタリングに手を出すことが出来ます。例えば、Dogクラスのhowlメソッドが返す文字列はハードコーディングされています。せめてstatic finalな定数として定義しておきたいですよね。そんなわけでDogクラスを以下のようにリファクタリングしてみます。


package net.sdls.barista.tech.utest;

public class Dog {
  static final String VOICE = "Bow bow!";

  /** 実行すると"Bow wow!"と吠えます */
  public static String howl() {
    return VOICE;
  }
}

うん、綺麗なコードにリファクタリングできたようです。では再びJUnitでテストを実行してみましょう。結果は右のようにエラーになってしまいなりました。よく見ると、"Bow wow!"と出力しなければいけないのに、"Bow bow!"と出力されています。このようにデグレ検出力が高いため、JUnitをつかえば、今までためらっていたクラスのリファクタリングが気軽に出来るようになります。結果、テストを作成する手間を上回る利益をでることが出来るでしょう。




今回はJUnitとは何かを理解してもらうために、非常に簡単な例を作成しました。次回以降はもっと具体的な使い方や、バージョンによる動作の違い、難易度の高い試験を実現するテクニック等について取り上げる予定です。

今回作成したサンプルソースは、全行本文中に記載済みですが、一応ダウンロードできるようにUPしておきます。興味のある方はdownloadして試してみてください。