Headline About TechLog Download Java VBA Link


January 21, 2008. Monday.

JUnitでテストファースト(2) - テストに合わせ実装を行う

前回のは実装クラスに先立ってJUnitによるテストを作成し、「コンパイル問題が未解決だ!」というエラーが表示されたところまでを記事にしました。今回は前回作ったJUnitテストコードに従ってクラスの実装を行います。なお、この記事は前回の続きとなっておりますので、未読の方はまず前回の記事を読んでいただけるようお願いいたします。




クラスの作成

「コンパイル問題がある」と怒られているのですから、とにかくクラスを作成します。前回記事中のsrcフォルダ内に、「設計」の項で作成したインターフェイスどおりにGreetingRobotクラスを作成します。ポイントは深く考え込まないことです。コンパイルできないと怒られているのですから、とにかくコンパイルを通すことが最優先です。



package net.sdls.barista.tech.robot;

package net.sdls.barista.tech.robot;

public class GreetingRobot {
  GreetingRobot(int year, int month, int date) {}
  void setName(String newName) {}

  public String getMessage() {
    return null;
  }
}


これでコンパイルが通るようになりました。「えぇ、実装は?」と言われそうですが、コンパイルを通すという目的にはかなっているので、これでかまいません。では早速テストを実行してみましょう。





メッセージが不正ですと怒られてしまいました。よくよくテストを見直すと、getMessage()の戻り値は「こんにちは。私の名前はデータです。」でないといけないと書いてあります。ですから、先ほどの実装を少し改造してみましょう。



  public String getMessage() {
    return "こんにちは。私の名前はデータです。";
  }


「えぇぇぇぇーーーっ」という声が聞こえそうですが、「テストを通す」という目的には最低限かなうコードです。とにかくテストを実行してみましょう。結果は、右の図のようにOKとなりました。これでGreetingRobotクラスの完成.....なんてはずはないですね。固定で返しているだけでは意味がありません。何がいけなかったのでしょうか。プログラミングが駄目?...違います。テストケースが足りないのです。

前回の記事中でGreetingRobotクラスは「名前をいつでも変えることが出来る」という仕様に設計したはずですので、それを盛り込んだ試験を作らなければなりません。したがって、GreetingRobotに手を入れる前に、GreetingRobotTestクラスにそれを検証するようなテストケースを追加します



  /**
   * 名前を次々に変更し、日本語で挨拶を取得するテスト
   * 設定した名前を用いたメッセージが表示されることを試験します。
   */
  public void testNameChange() {
    String[] names = {"データ", "ロア", "アトム", "ウラン"};
    GreetingRobot robot = new GreetingRobot(2007, 10, 20);

    for (int i = 0; i < names.length; i++) {
      robot.setName(names[i]);
      String message = robot.getMessage();
      String answer = "こんにちは。私の名前は" + names[i] + "です。";
      if (!answer.equals(message)) {
        fail(answer + " != " + message);
      }
    }
  }


名前を配列に格納し、いろんな名前をセットしては結果を検証するようなテストを追加作成しました。さて再び試験を実行すると結果は以下のようになります。





ちゃんとエラーとして検出されました。テスト結果に従い、名前の変更に対応できるよう、プログラムを以下のように直します。



  private String name;
  void setName(String newName) {
    this.name = newName;
  }

  public String getMessage() {
    return "こんにちは。私の名前は" + name + "です。";
  }


さて、再度テストを実行してみましょう。結果は右のようにオールグリーン。成功です。

このようにTestFirstなプロジェクトでは、問題が発生したら、まずそれを検証するテストケースを作り、その後にプログラムを修正します。テストケースを作るというと随分面倒な話に聞こえますが、要は問題が発生したときのデータをその場でテストケースに盛り込めばいいのですから、プログラムを直してから「あれ、どんなデータで試したんだっけ?」と再現に悩むよりよっぽど建設的です。




段々とかたちになってきましたが、上記のテストではまだ仕様を満たすか検査するのには不足です。複数インスタンスが問題なく扱えるか、製造年月日に正しい日付が設定できるかなど、検証しておくべき試験は多々あります。これまでのペースでだらだらと続けても仕方がありませんので、ここに完成したテストコードと実装コードのサンプルをおいておきます。興味のある方はダウンロードしてみてください。


さて、次回は完成したクラスに対して仕様変更を行いたいと思います。



Next: JUnitでテストファースト(3) - 仕様変更への対応 >>