web-dev-qa-db-ja.com

JUnit 4でテストスイートを動的に作成するにはどうすればよいですか?

JSuite 4を使用して、含まれるテストクラスの名前がテストスイートが実行されるまでわからないjunitテストスイートを作成したいと思います。

JUnit 3ではこれを行うことができました:

_public final class MasterTester extends TestCase
{
  /**
   * Used by junit to specify what TestCases to run.
   * 
   * @return a suite containing what TestCases to run
   */
  public static TestSuite suite() {
    TestSuite suite = new TestSuite();

    for(Class<?> klass : gatherTestClasses()) {
      suite.addTestSuite(klass);
    }

    return suite;
  }
}
_

gatherTestClasses()メソッドに、実行するテストクラスの判別を処理させます。

JUnit 4では、 documentation は注釈を使用するように指示します:@SuiteClasses({TestClass1.class, TestClass2.class...})はテストスイートをビルドします。 多数SO回答 これを行う方法を示しています。残念ながら、私が見る例では、動的に生成されたTestClassesのリストを渡すことができません。

この SOの答え は、私がしたくない_BlockJUnit4ClassRunner_をサブクラス化する必要があることを示唆しています。

動的に指定されたテストスイートは、JUnit 4のどこかにある必要があるように見えます。誰もがどこを知っていますか?

51
Tom Tresansky

テストクラスで命名規則を使用すると、クラスパススイートが非常に便利であることがわかりました。

https://github.com/takari/takari-cpsuite

以下に例を示します。

import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;

@RunWith(ClasspathSuite.class)
@ClassnameFilters({".*UnitTest"})
public class MySuite {
}
26
JavaRocky

動的なテストスイートを作成するには、_@RunWith_アノテーションを使用する必要があります。それを使用する2つの一般的な方法があります。

@RunWith(Suite.class)

これにより、問題のテストスイートを構成するクラスを指定できます。これは、JUnit 3スタイルと同等です。

_import junit.framework.TestSuite;
import junit.framework.TestCase;

public final class MasterTester extends TestCase {

  public static TestSuite suite() {
    TestSuite suite = new TestSuite();
    suite.addTestSuite(TestClass1.class);        
    suite.addTestSuite(TestClass2.class);
    // etc...
    return suite;
  }
}
_

同等のJUnit 4クラスは次のとおりです。

_import org.junit.runners.Suite;

@RunWith(Suite.class)
@SuiteClasses({TestClass1.class, TestClass2.class})
public final class MasterTester {

}
_

@RunWith(AllTests.class)

これにより、テストスイートを構成するテストを動的に指定できます。テストが実行時までわからない場合は、アノテーションでテストを指定できません。代わりにこの構造を使用できます。したがって、JUnit 3コードが次の場合:

_import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.framework.Test;

public final class MasterTester extends TestCase {

  public static TestSuite suite() {
    TestSuite suite = new TestSuite();
    for (Test test : findAllTestCasesRuntime()) {
      suite.addTest(test);
    }
    return suite;
  }
}
_

同等のJUnit 4コードは次のとおりです。

_import org.junit.runners.AllTests;
import junit.framework.TestSuite;
import junit.framework.Test;

@RunWith(AllTests.class)
public final class MasterTester {

  public static TestSuite suite() {
    TestSuite suite = new TestSuite();
    for (Test test : findAllTestCasesRuntime()) {
      suite.addTest(test);
    }
    return suite;
  }
}
_
36
Danail Nachev

私はJUnit 4.8を使用してこれを試しましたが、動作します:

@RunWith(AllTests.class)
public class SomeTests
{
    public static TestSuite suite()
    {
        TestSuite suite = new TestSuite();

        suite.addTest(new JUnit4TestAdapter(Test1.class));
        suite.addTest(new JUnit4TestAdapter(Test2.class));

        return suite;
     }
}
36
Andrejs

GatherTestClasses()が何をするのかはわかりませんが、OSがLinuxの場合はいくつかのテストを返し、OSがWindowsの場合は別のテストを返します。 仮定 を使用して、JUnit 4.4でそれを複製できます。

_@Test
public void onlyOnLinux() {
    assumeThat(getOS(), is(OperatingSystem.LINUX));
    // rest of test
}

@Test
public void onlyOnWindows() {
    assumeThat(getOS(), is(OperatingSystem.WINDOWS));
    // rest of test
}

@Test
public void anyOperatingSystem() {
    // just don't call assumeThat(..)
}
_

getOS()およびOperatingSystemの実装はカスタムコードです。

6
Brad Cupit

これを実装する方法の完全な例を次に示します。 2つのtestCaseクラスと1つのスイートの組み合わせです。

  1. ExampleInstrumentedTest:

    _import Android.support.test.rule.ActivityTestRule;
    
    import org.junit.Rule;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.JUnit4;
    
    @RunWith(JUnit4.class)
    public class ExampleInstrumentedTest {
    
    
        @Rule
        public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
    
        @Test
        public void checkInputs() throws Exception {
    
        }
    }
    _
  2. ExampleInstrumentedTest2:

    _import Android.support.test.rule.ActivityTestRule;
    
    import org.junit.Rule;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.junit.runners.JUnit4;
    
    @RunWith(JUnit4.class)
    public class ExampleInstrumentedTest2 {
    
    
        @Rule
        public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);
    
        @Test
        public void checkInputs() throws Exception {
    
        }
    }
    _
  3. ExampleInstrumentedSuite:

    _import junit.framework.TestSuite;
    
    import org.junit.runner.RunWith;
    import org.junit.runners.AllTests;
    
    @RunWith(AllTests.class)
    public class ExampleInstrumentedSuite {
    
        public static TestSuite suite() {
            TestSuite suite = new TestSuite();
            suite.addTest(new junit.framework.JUnit4TestAdapter(ExampleInstrumentedTest.class));
            suite.addTest(new junit.framework.JUnit4TestAdapter(ExampleInstrumentedTest2.class));
            return suite;
        }
    }
    _

TestCaseクラスでは、デフォルトの@RunWith(JUnit4.class)の代わりに@RunWith(AndroidJUnit4.class)を使用する必要があることに注意してください。

0
Maher Abuthraa