如何在JUnit 4中dynamic创buildtesting套件?

我想创build一个使用JUnit 4的junittesting套件,在testing套件运行之前,要包含的testing类的名字是不知道的。

在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()方法处理确定要运行的testing类。

在JUnit 4中, 文档说使用一个注释: @SuiteClasses({TestClass1.class, TestClass2.class...})构build我的testing套件。 有很多SO答案显示如何做到这一点。 不幸的是,我看到的例子似乎不允许传递一个dynamic生成的TestClass列表。

这个答案build议我将不得不BlockJUnit4ClassRunner ,我不想这样做。

dynamic指定的testing套件看起来像某些地方必须在JUnit 4中。 有谁知道在哪里?

在我的testing类中使用命名约定时,我发现Classpath套件非常有用。

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 { } 

我试过这个使用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; } } 

要创builddynamictesting套件,您需要使用@RunWith注释。 有两种常用的方法来使用它:

@RunWith(Suite.class)

这使您可以指定哪些类组成所讨论的testing套件。 这相当于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)

这使您可以dynamic指定组成testing套件的testing。 如果您的testing直到运行时才知道,则不能在注释中指定它们。 你可以使用这种结构。 所以,如果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; } } 

我不确定gatherTestClasses()是做什么的,但是假设它在操作系统是Linux时返回一些testing,在操作系统是Windows时返回不同的testing。 你可以在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是您的自定义代码的实现。

这里是一个完整的例子如何实现。 它结合了两个testCase类和一个套件。

  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)