home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

Java/JUnit/"test"接頭辞無しの"@Test"メソッドが認識されない

Java/JUnit/"test"接頭辞無しの"@Test"メソッドが認識されない

Java / JUnit / "test"接頭辞無しの"@Test"メソッドが認識されない
id: 806 所有者: msakamoto-sf    作成日: 2010-10-13 16:47:52
カテゴリ: Java 

JUnit 4.8.1 使用中に、

public class FooTest extends TestCase {
    @Test
    public void foo {
        assertTrue(true);
    }
}

がElipse/Maven双方から認識されない現象に遭遇したのでメモ。

環境:

JUnit : 4.8.1
POM : 
    <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.8.1</version>
     <scope>test</scope>
   </dependency>

Maven : 2.2.1
Eclipse : 3.5 Galileo
 org.eclipse.jdt.junit (3.5.1.r351_v20090708-0800)
 org.eclipse.jdt.junit.runtime (3.4.100.v20090513-2000)
 org.eclipse.jdt.junit4.runtime (1.1.0.v20090513-2000)
 org.eclipse.pde.junit.runtime (3.4.0.v20090527)
 org.junit (3.8.2.v20090203-1005)
 org.junit4 (4.5.0.v20090824)
JDK 1.6.12
Windows XP SP2 / 2GB RAM / Pen4 HT

現象

前掲のFooTestクラス一つだけの状態で、Eclipse上からJUnit実行 or "mvn test" を実行すると「テストケースが見つかりません」という趣旨のエラーになる。

発生時のスタックトレース(Eclipse経由):

junit.framework.AssertionFailedError: No tests found in echoes.act9.protocol.FooTest
	at junit.framework.Assert.fail(Assert.java:47)
	at junit.framework.TestSuite$1.runTest(TestSuite.java:97)
	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:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

発生時のスタックトレース(Maven経由):

-------------------------------------------------------------------------------
Test set: echoes.act9.protocol.FooTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.094 sec <<< FAILURE!
warning(junit.framework.TestSuite$1)  Time elapsed: 0.016 sec  <<< FAILURE!
junit.framework.AssertionFailedError: No tests found in echoes.act9.protocol.FooTest
	at junit.framework.Assert.fail(Assert.java:47)
	at junit.framework.TestSuite$1.runTest(TestSuite.java:97)
	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:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
	at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
	at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
	at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345)
	at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009)

メソッド名に"test"接頭辞を付与すると認識され、テストケースが実行される。

原因

ClassRunnerの内部判定処理でJUnit3.8.x用のClassRunnerが選択されてしまう為、"@Test"アノテーションが認識されなかったことが原因。

Eclipse上のスタックトレース:

...
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
...

Maven上のスタックトレース:

...
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
...

参考:

対処法

テストクラスの宣言に以下のアノテーションを付与する。

...
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
...
@RunWith(JUnit4.class)
public class FooTest extends TestCase {
...

上に挙げた "RunWith helps JUnit" の記事では "JUnit4ClassRunner.class" を使っているが、JUnit-4.8.1においてはdeprecatedにされている。JavaDocを調べたところ、4.8.1においては"org.junit.runners.JUnit4"を使うと良いようだ。
"org.junit.runners.BlockJUnit4ClassRunner" というのもあるが、JavaDocで

Developers wanting to explicitly tag a class as a JUnit 4 class should use @RunWith(JUnit4.class), 
not, for example in JUnit 4.5, @RunWith(BlockJUnit4ClassRunner.class).

とあるため、JUnit4.classの方を採用した。

以上の対処により、Eclipse, Maven 共に@Testアノテーションが認識されるようになった。



プレーンテキスト形式でダウンロード
現在のバージョン : 1
更新者: msakamoto-sf
更新日: 2010-10-13 17:18:35
md5:272d0164d886f90355bf37341f85077b
sha1:ac176165d8f9b7a1729676c403a10bac27cb118b
コメント
コメントを投稿するにはログインして下さい。