Index: [Article Count Order] [Thread]

Date:  Wed, 26 Apr 2000 19:06:37 +0900
From:  firo <firo@....jp>
Subject:  [XP-jp:00270] Re: JUnit 利用方法
To:  extremeprogramming-jp@....jp (extremeprogramming-jp ML)
Message-Id:  <00Apr26.190754jst.115201@....jp>
References:  <B52BD0C8.1178%khosokawa@....com> <00Apr26.130159jst.115201@....jp>
Posted:  Wed, 26 Apr 2000 19:07:54 +0900
X-Mail-Count: 00270

矢崎です。続きです。

firo wrote:

>
> >
> >
> > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > 3.必要ならばsetUpメソッドをオーバライドする。原則的に
> > >  はオーバライドすることになるでしょう。何をするかというと、
> > >  ユニットテストをする対象のオブジェクトをnewする。
> > >  newしたオブジェクトを入れておくためのインスタンス変数
> > >  も定義する。
> > >
> > > import junit.framework.*;
> > >
> > > public class ConcreteTestCase extends TestCase{
> > >
> > > /*以下の変数は任意。型はテストしたいクラス。数も自由*/
> > > TestTarget aTestTarget;                  //3
> > >
> > > public ConcreteTestCase(String name){
> > > super(name);
> > > }
> > >
> > > /*setUpはリターンはvoid。引数はなしじゃないとだめ。*/
> > > public void setUp(){                     //3
> > > aTestTarget = new TestTarget();   //3
> > > }                                        //3
> > >
> > > }
> > >
> >
> > 例えば、setUp()でファイルをオープンしようとして、エラーになった場合、例外で
> > 戻るのでしょうか?どこへ戻るのでしょうか?
>

setUp()と、tearDown()は、TestCaseクラスに空の
メソッドとしてあって、以下のようになっています。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected void setUp() throws Exception {
}

protected void tearDown() throws Exception {
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ポイントは、throws節です。

ConcreteTestCaseは、ご承知のとおりTestCaseのサブクラス
で、setUp()とtearDown()をオーバライドします。
したがって、もしsetUp()やtearDown()で例外が発生する可能
性がある場合、以下の2通りのいずれかのやり方で対処しなけ
ればなりません。

1.オーバライドするsetUp()やtearDown()に、Exception又は
Exceptionのサブクラスを伴うthrows節を宣言する。
   ex.
      public void setUp() throws IOException{
         aTestTarget = new TestTarget();
      }

2.setUp()やtearDown()の中で、try-catch節を使う。
   ex.
      public void setUp(){
         try{
             aTestTarget = new TestTarget();
         }catch(Throwable e){
             .......
         }
      }

1の方法をとった場合、throwされたExceptionは、どうなるか
というと、TestResultクラスのインスタンスが拾ってくれます。
よって、複数のテストをする場合でも、途中で終わったりせず、
最後まで実行されます。しかし、この途中で、とか最後まで、
とかいうことを正確に説明するのがちょっと難しいので、ご質問
から少しはずれて、JUnitの動きそのものを少しだけ、以下に説明
します。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
私の書いた例の場合、JUnitを実行すると、ConcreteTestCaseの
インスタンスが、テストメソッドの数だけnewされます。それぞれ
のインスタンスは、名前を持ちます。それは、テストメソッドの
名前になります。例でいえば、"testXXX"という名前を持つ、
ConcreteTestCaseのインスタンス、"testYYY"という名前を持つ
ConcreteTestCaseのインスタンス、"testZZZ"という名前を持つ
ConcreteTestCaseのインスタンスの計3インスタンスが生成され
るわけです。

そしてJUnitは、上のインスタンス1つ1つを順に実行します。
それぞれのインスタンスは、自分と同じ名前のテストメソッドだけ
を実行します。

つまり、、、

"testXXX"という名前を持つインスタンスが実行されたときには、
setUP(),testXXX(),tearDown()が実行されます。
"testYYY"という名前を持つインスタンスが実行されたときには、
setUP(),testYYY(),tearDown()が実行されます。
"testZZZ"という名前を持つインスタンスが実行されたときには、
setUP(),testZZZ(),tearDown()が実行されます。

各インスタンスは独立していて、何ら連携して動作しません。
setUP()とtearDown()は、ロジックは同じものを使いますが、
そこで生成されるオブジェクトは、インスタンスとしてはまった
く別ものです。生成の仕方だけを等しくしているだけです。

例でいえば、
    public void setUp(){
        aTestTarget = new TestTarget();
    }

となっていますが、各ConcreteTestCaseのインスタンスは、それ
ぞれ、他の2つとはまったく独立にsetUP()を行い、別々のインス
タンスを生成し、そのインスタンスに対して、まったく独立に1つ
だけのテストメソッドを実行し、終了するという具合です。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
で、ご質問に戻りますと、例えば、"testXXX"という名前がついた
インスタンスのsetUP()で例外が発生した場合、それがthrows節で
捕まえられた場合には、先述したとおり、TestResultクラスのイ
ンスタンスが拾ってくれます。そしてそのインスタンスの処理は
そこでおしまいです。testXXX()は実行されません。しかし、別の
インスタンスの実行までをとめることはしません。よって、
"testYYY"、"testZZZ"インスタンスの実行は行われます。

#もっとも、例の場合は全て同じsetUP()を使いますから、いずれの
場合もsetUP()で例外が発生してしまうでしょうけど、、、

#私の例ではふれていませんが、JUnitでは、TestCaseの異なるサブ
クラス(のインスタンス)をいっしょに実行できます。この場合、
setUp()で例外が発生するものもあれば、そうならないものも混在
することがあるわけです。

#補足ですが、
私の例では、setUpはテストをターゲットするクラスのインスタンス
を生成しているだけですが、もちろんテストの内容によっては、それ
以外の処理も行わなければなりません。System.out.printlnなんか
やってもかまいません。

残りはまた後で、、、

--
矢崎博英  firo@....jp