我想使用JUnit 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...})
来构建我的测试套件。有numerous SO answers显示如何执行此操作。不幸的是,我看到的示例似乎不允许传递动态生成的TestClasses列表。
这SO answer建议我必须继承BlockJUnit4ClassRunner
这是我不想做的。
动态指定的测试套件似乎必须在某个地方的JUnit 4中。有谁知道在哪里?
答案 0 :(得分:36)
我已经尝试使用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;
}
}
答案 1 :(得分:35)
要创建动态测试套件,您需要使用@RunWith
注释。有两种常用方法可供使用:
<强> @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;
}
}
答案 2 :(得分:26)
我发现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 {
}
答案 3 :(得分:6)
我不确定gatherTestClasses()是做什么的,但是假设它在操作系统是Linux时会返回一些测试,而在操作系统是Windows时会返回不同的测试。您可以使用assumptions在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
的实施是您的自定义代码。
答案 4 :(得分:0)
这是一个如何实现它的完整示例。它结合了两个testCase类和一个套件。
<强> 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 {
}
}
<强> 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 {
}
}
<强> 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)
答案 5 :(得分:0)
public class MyTestCase extends TestCase {
@Override
public void runTest() {
// define assertion here <===
assertEquals("yes", "yes");
}
}
@RunWith(AllTests.class)
public class DynamicTestSuite {
public static TestSuite suite() {
TestSuite suite = new TestSuite();
// dynamically create your test case here <====
suite.addTest(new MyTestCase());
return suite;
}
}