2012年4月7日土曜日

JUnit入門―導入・実行編(コンソールver.)


今回は、JUnitをコンソールから使うための環境作りについて試してみます。
ここでは、JDKはすでにインストールされているものとします。
JDKのインストールについては、以下のページなどを参考にしてみてください。

http://www.javadrive.jp/install/jdk/

使用している環境は以下の通りです。
・Windows 7 SP1
・JDK 1.7.0 (64bit ver.)

・JUnitの導入

まず、JUnitのJarファイルなどをダウンロードします。

現時点(2012/3)での最新版である4.10は、github上にあります。
github上には、4.7までのJUnitをダウンロードすることができるようになっています。
https://github.com/KentBeck/junit/downloads

それより以前のバージョンのものはsorceforgeにあります。
よく見ると、sorceforge上にも4.10まであるようです。
http://sourceforge.net/projects/junit/files/junit/

上記ページから、zipファイルかtarファイルをダウンロードして、適当なところに展開します。
ここでは比較のため、4.10と3.8.1をダウンロードします。
それぞれ、「junit4.10」、「junit3.8.1」というディレクトリに展開すると、各ディレクトリ直下に「junit-4.10.jar」または「junit.jar」があります。

・テストの実行

3.x系と4.x系で実行の仕方が大きく異なります。

3.x系

3.x系では、CUIで実行する方法・swingのGUIで実行する方法・awtのGUIで実行する方法の3週類があります。
ここでは、junitに付属しているサンプルをそれぞれの方法で実行してみます。

1.CUIで実行する方法

先程展開したディレクトリで、以下のコマンドを実行します。

\junit3.8.1> java -cp junit.jar;. junit.textui.TestRunner junit.samples.SimpleTest

junit.texui.TestRunnerというものがテストクラス実行のためのクラス(テストランナー)になります。
その後に、テストクラス名を引数で指定します。
テストクラスは1つしか指定できないようです。
実行結果は以下のようになります。

.E.F.F
Time: 0.002
There was 1 error:
1) testDivideByZero(junit.samples.SimpleTest)java.lang.ArithmeticException: / by zero
        at junit.samples.SimpleTest.testDivideByZero(SimpleTest.java:49)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
There were 2 failures:
1) testEquals(junit.samples.SimpleTest)junit.framework.AssertionFailedError: Size expected:<12> but was:<13>
        at junit.samples.SimpleTest.testEquals(SimpleTest.java:56)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
2) testAdd(junit.samples.SimpleTest)junit.framework.AssertionFailedError
        at junit.samples.SimpleTest.testAdd(SimpleTest.java:45)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
FAILURES!!!
Tests run: 3,  Failures: 2,  Errors: 1

3つのテストケースを実行して、検証の失敗(Failures)が2つ、実行時のエラー(Errors)が1つという結果になっています。
失敗とエラーの違いは、assertionによる例外か、それ以外の例外かというものです。

2.swingのGUIで実行する方法

先程と同様にjunitのディレクトリで、以下のコマンドを実行します。

\junit3.8.1> java -cp junit.jar;. junit.swingui.TestRunner junit.samples.SimpleTest

すると、以下のようなGUIが表示されます。



結果は先ほどと同様ですが、中央に赤いバーが表示されていて、結果を視覚的に確認することができます。
また、上段の「Run」ボタンを押下するとテストクラスの再実行が、中段の「Run」を押下すると各テストケースごとの実行ができます。

3.awtのGUIで実行する方法

awtの場合も、swingと同様の実行法になります。

\junit3.8.1> java -cp junit.jar;. junit.awtgui.TestRunner junit.samples.SimpleTest

すると、以下のようなGUIが表示されます。


こちらのGUIでもテストクラスの再実行とテストケースごとの実行ができるようになっています。

4.x系

4.x系では、3.x系のようなGUIのテストランナーのクラスは用意されていません。
さらに、コマンドライン上で実行するためのテストランナークラスも変更されています。
コマンドは以下の通りです。

\junit4.10> java -cp junit-4.10.jar;. org.junit.runner.JUnitCore junit.samples.SimpleTest

こちらでは「org.junit.runner.JUnitCore」というクラスがテストランナーになっています。
出力結果も若干変わっています。

JUnit version 4.10
.E.E.E
Time: 0.005
There were 3 failures:
1) testDivideByZero(junit.samples.SimpleTest)
java.lang.ArithmeticException: / by zero
        at junit.samples.SimpleTest.testDivideByZero(SimpleTest.java:54)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:243)
        at junit.framework.TestSuite.run(TestSuite.java:238)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:24)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
        at org.junit.runner.JUnitCore.runMain(JUnitCore.java:98)
        at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:53)
        at org.junit.runner.JUnitCore.main(JUnitCore.java:45)
2) testAdd(junit.samples.SimpleTest)
junit.framework.AssertionFailedError
        at junit.framework.Assert.fail(Assert.java:48)
        at junit.framework.Assert.assertTrue(Assert.java:20)
        at junit.framework.Assert.assertTrue(Assert.java:27)
        at junit.samples.SimpleTest.testAdd(SimpleTest.java:48)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:243)
        at junit.framework.TestSuite.run(TestSuite.java:238)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:24)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
        at org.junit.runner.JUnitCore.runMain(JUnitCore.java:98)
        at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:53)
        at org.junit.runner.JUnitCore.main(JUnitCore.java:45)
3) testEquals(junit.samples.SimpleTest)
junit.framework.AssertionFailedError: Size expected:<12> but was:<13>
        at junit.framework.Assert.fail(Assert.java:50)
        at junit.framework.Assert.failNotEquals(Assert.java:287)
        at junit.framework.Assert.assertEquals(Assert.java:67)
        at junit.framework.Assert.assertEquals(Assert.java:199)
        at junit.samples.SimpleTest.testEquals(SimpleTest.java:62)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at junit.framework.TestCase.runTest(TestCase.java:168)
        at junit.framework.TestCase.runBare(TestCase.java:134)
        at junit.framework.TestResult$1.protect(TestResult.java:110)
        at junit.framework.TestResult.runProtected(TestResult.java:128)
        at junit.framework.TestResult.run(TestResult.java:113)
        at junit.framework.TestCase.run(TestCase.java:124)
        at junit.framework.TestSuite.runTest(TestSuite.java:243)
        at junit.framework.TestSuite.run(TestSuite.java:238)
        at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:24)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
        at org.junit.runner.JUnitCore.runMain(JUnitCore.java:98)
        at org.junit.runner.JUnitCore.runMainAndExit(JUnitCore.java:53)
        at org.junit.runner.JUnitCore.main(JUnitCore.java:45)
FAILURES!!!
Tests run: 3,  Failures: 3

大きな違いとしては、Errorsがなくなり、すべてFailuresに統一されている点でしょうか。
あとは、バージョン番号なんかも表示されるようになっていますね。

なお、4.x系では引数のテストクラスを複数指定することができるようになっています。
以下のように、引数にテストクラスを指定していけば、全て実行してくれます。

\junit4.10> java -cp junit-4.10.jar;. org.junit.runner.JUnitCore junit.samples.SimpleTest

0 件のコメント:

コメントを投稿