[英]How do I Dynamically create a Test Suite in JUnit 4 when the test files are not extending to TestCase?
[英]How do I Dynamically create a Test Suite in JUnit 4?
我想使用 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 中,文档说使用注释: @SuiteClasses({TestClass1.class, TestClass2.class...})
来构建我的测试套件。 有许多 SO 答案显示了如何做到这一点。 不幸的是,我看到的示例似乎不允许传递动态生成的 TestClass 列表。
这个SO 答案建议我必须将BlockJUnit4ClassRunner
子类BlockJUnit4ClassRunner
,而我不想这样做。
动态指定的测试套件似乎必须在 JUnit 4 中的某个地方。 有谁知道在哪里?
要创建动态测试套件,您需要使用@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;
}
}
我已经使用 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;
}
}
我发现 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 {
}
我不确定 gatherTestClasses() 做了什么,但假设它在操作系统是 Linux 时返回一些测试,当操作系统是 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
是您的自定义代码。
这是一个如何实现的完整示例。 它结合了两个 testCase 类和一个套件。
示例仪器测试:
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 { } }
示例 InstrumentedTest2:
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 { } }
示例InstrumentedSuite:
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 Class 中使用@RunWith(JUnit4.class)
而不是默认的@RunWith(AndroidJUnit4.class)
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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.