362291 ランダム
 HOME | DIARY | PROFILE 【フォローする】 【ログイン】

何でも書き込もう

第4回:JUnitにおけるTestCaseの作り方

第4回:

JUnitにおけるテストケースの作り方1
JUnitにおけるテストケースの作り方2

********************************

JUnitにおけるテストケースの作り方1

どうも、最近夜中に記事を書いている管理人です。
妙にナチュラルハイな感じです。

では、早速講座をはじめましょう。

前回は、カンタンなテストケースを作成しました。
今回は、今までに何回も出てきたassertEqualsについてもう少し深く見てみます。

assertEqualsの概要は今までの講座で理解できていると思います。
assertEquals( a, b )のaとbを比較するというメソッドですね。
このa,bは実はいろんな型でOKです。
っというか、どんな型でもOKといった方がいいかもしれません。

たとえばint型に代表されるプリミティブ型もOKですし、参照型もOKです。

なので
assertEquals( true, method() );//boolean
assertEquals( 10, method() );//int
assertEquals( "abc", method() );//参照型

これはどんな返り値型をもつメソッドでもテストできるということですね。
詳しくはAPIを見るとよいでしょう。

ではここからは、少し練習問題を交えながら、レベルアップしていきましょう。

まず、以下のメソッドをテストするJUnitプログラムを作ってみてください。

Target.java
------------------------------
public class Target{
 public int getLength( String str ){
  retrun str.length();
 }
}

単純なJavaプログラムですね。
文字列の長さをint型で返すだけです。
これのテストプログラムはどんなものになるでしょうか??

みなさん、よろしければ、コメントでプログラムを残してみてください。
別に動かなくてもいいです。
失敗しててもいいです。
恥ずかしいこたぁありません。
私だって勉強不足なので、皆さんがどのようなプログラムを書いてこられるか・・・逆に勉強させていただきたいくらいです。
でもプロの方はご遠慮をば・・・
逆にアドバイスなど、残していただけるとうれしいです。

私の例としては、

Test.java
---------------------------------------
import junit.framework.TestCase;
public class Test extends TestCase {
 public Test(String arg0) {
  super(arg0);
 }
 public void testGetLength(){
  Target target = new Target();
  assertEquals( 1, target.getLength( "a" ) );
  assertEquals( 2, target.getLength( "ab" ) );
  assertEquals( 0, target.getLength( "" ) );
  assertEquals( 0, target.getLength( null ) );//失敗
 }
}

このテストプログラムは最後のテスト(nullのとき)で失敗しますね。
だって、nullの時は、str.length()文でNullPointerExceptionが発生しますからね。

まぁ、逆にこのテストをやったおかげで、これに気付いた!という感じでしょうか。

では、もっと高度なものを。
Target2.java
------------------------------
public class Target2{
 public int getLength( String str1, String str2 ){
  retrun this.getLength( str1 ) + this.getLength( str2 );
 }
 
 public int getLength( String str ){
  retrun str.length();
 }

}

このgetLength( String str1, String str2 )をテストするプログラムはどう書きます??
ただし、getLength( String str )はテスト済みでないという状況とします。
次回までにちょっと考えてみましょう。
これもできればコメントで残してみてくださいね。


JUnitにおけるテストケースの作り方2


寒くなってきましたね。
コタツ&鍋が恋しい季節です。

さて、今回はJUnitのテストケースの作り方をもっと詳しく勉強しましょう。
前回以下のようなJavaサンプルプログラムをテストしてねと掲載しました。

Target2.java
------------------------------
public class Target2{
 public int getLength( String str1, String str2 ){
  retrun this.getLength( str1 ) + this.getLength( str2 );
 }
 public int getLength( String str ){
  retrun str.length();
 }
}

getLength( String str1, String str2 )をテストするとき、どう考えます?

「getLength( String str1, String str2 )をテストする前にgetLength( String str )のテストをしないとね」

そうですね。その通りです。
じゃーどんな感じになりますかね??

「えーーと、getLength( String str )のテストも考えないといけないし、テストケースとしては
・str1,str2が0の時
・str1,str2がNULLの時
・str1,str2が1以上のとき
の3パターンじゃないかな」

おお、たしかに。
これだけすれば、とりあえずはOKでしょう。
でも、getLength( String str1, String str2 )のテストのはずなのに、getLength( String str )のテストのことも考えているのは変ジャーありません?

「確かにそうだけど、でもgetLength( String str1, String str2 )がgetLength( String str )を呼び出しているのだから、しょうがないよ。」

しょうがないかぁ・・・
まぁ、このくらいのJavaプログラムのテストならそれもアリかもしれません。
しかし、以下のようなJavaプログラムをテストして!!っていわれたら大変ですよ?

Target3.java
------------------------------------------
public int targetMethod(){
 int answer = 0;
 answer = otherMethod1();
 answer = otherMethod2( answer );
 answer = answer + otherMethod3(answer);
 answer = answer + otherMethod4(answer);
 answer = answer + otherMethod5(answer);
 answer = answer + otherMethod6(answer);
 return answer;
}

どうです?もしtargetMethodをテストしてって言われたら・・・
大変ですよね?
otherMethod1~6までのすべてのテストケースを考えないといけないし、さらに、そのパターン数もハンパではありません。
単純計算すると
otherMethod1のテストケース数×otherMethod2のテストケース数・・・・×otherMethod6のテストケース数
がtargetMethodのテストケース数になります。

内部で呼び出しているメソッドが6つだからいいものの、100個あるとどうなります??
もうわけわかりませんねぇ。
しかも当然otherMethod1~6のテストもtargetMethodのテストとは別にやることになるでしょう。

「はぁーなるほどぉ。各メソッドのテストケースの掛け算が総テスト数になっているねぇ」
「じゃーどうやってやるのよう?」

答えは簡単です。
otherMethod1~6のテストは通常どおり行います。
問題はtargetMethodですよね。
これはスタブメソッドを使いましょう。

「スタブメソッド?」

そうです。
とりあえず、Javaサンプルを掲載しますね。

Target2.java
------------------------------
public class Target2{
 public int getLength( String str1, String str2 ){
  retrun getLength( str1 ) + getLength( str2 );
 }
 protected int getLength( String str ){
  retrun str.length();
 }
}

Target2Stub.java
------------------------------
public class Target2Stub extends Target2{
 protected int getLength( String str ){
  retrun 1;
 }
}

JavaTest.java
------------------------------
public testGetLength(){
 Target2Stub target = new Target2Stub();
 assertEquals( 2, target.getLength( "1", "1" ) );
}

どうでしょう?
理解できます?

まず、今回テストしたいのはgetLength( String str1, String str2 )ですよね?
ということは、getLength( str1 )の結果が足し算できているかどうかをテストすればよいわけです。
getLength( str1 )のテストはする必要はありません。

ってことは、足し算ができているかどうかだけの話ですよね?
だったらサブクラスに1を返すgetLength( String str )をオーバーライドしたメソッドを用意すればOKではありません?
そのサブクラスのメソッドをgetLength( String str1, String str2 )から呼び出すことになるので、結局2が返ってくればOKとなります。

このサブクラスのオーバーライドしたメソッドをスタブといいます。
本当のgetLength( String str )メソッドを呼び出していると先ほどのようなことになるので、なんちゃってメソッドを用意して、それを呼び出すことでテストを簡単化しています。

さらに、本当のgetLength( String str )は実装できていないということも考えられます。
この場合にもこのスタブが役に立ちますね。

いかがでしたか?
スタブメソッド、、理解できましたでしょうか?

まぁ、ちと例が悪かったので、難しかったかもしれませんね。
反省しています・・・(T_T)

次回は、もっと高度なスタブメソッドをもっといい例で勉強してみます。



Copyright (c) 1997-2019 Rakuten, Inc. All Rights Reserved.