Java 如何在 JUnit 4 中动态创建测试套件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3257080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I Dynamically create a Test Suite in JUnit 4?
提问by Tom Tresansky
I would like to create a junit test suite using JUnit 4 where the names of the test classes to be included are not known until the test suite is run.
我想使用 JUnit 4 创建一个 junit 测试套件,其中要包含的测试类的名称在测试套件运行之前是未知的。
In JUnit 3 I could do this:
在 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;
}
}
and let the gatherTestClasses()
method deal with figuring out what test classes to run.
并让gatherTestClasses()
方法处理找出要运行的测试类。
In JUnit 4, the documentationsays to use an annotation: @SuiteClasses({TestClass1.class, TestClass2.class...})
to build up my test suite. There are numerous SO answersshowing how to do this. Unfortunately the examples I see do not seem to allow for passing a dynamically generated list of TestClasses.
在 JUnit 4 中,文档说使用 annotation: @SuiteClasses({TestClass1.class, TestClass2.class...})
to build up my test suite。有许多 SO 答案显示了如何做到这一点。不幸的是,我看到的示例似乎不允许传递动态生成的 TestClass 列表。
This SO answersuggested I would have to subclass BlockJUnit4ClassRunner
which I do not want to do.
这个SO 答案表明我必须将BlockJUnit4ClassRunner
我不想做的子类化。
Dynamically specified test suites seem like something that must be in JUnit 4 somewhere. Does anyone know where?
动态指定的测试套件似乎必须在 JUnit 4 中的某个地方。有谁知道在哪里?
采纳答案by JavaRocky
I found Classpath suite quite useful when used with a naming convention on my test classes.
我发现 Classpath 套件在与我的测试类的命名约定一起使用时非常有用。
https://github.com/takari/takari-cpsuite
https://github.com/takari/takari-cpsuite
Here is an example:
下面是一个例子:
import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.runner.RunWith;
@RunWith(ClasspathSuite.class)
@ClassnameFilters({".*UnitTest"})
public class MySuite {
}
回答by Brad Cupit
I'm not sure what gatherTestClasses() does, but let's say it returns some tests when the OS is Linux and different tests when the OS is Windows. You can replicate that in JUnit 4.4 with assumptions:
我不确定 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(..)
}
The implementation of getOS()
and OperatingSystem
being your custom code.
实现getOS()
并OperatingSystem
成为您的自定义代码。
回答by Danail Nachev
To create a dynamic test suite, you need to use the @RunWith
annotation. There are two common ways to use it:
要创建动态测试套件,您需要使用@RunWith
注释。有两种常见的使用方法:
@RunWith(Suite.class)
@RunWith(Suite.class)
This allows you to specify, which classes compose the test suite in question. This is equivalent to the JUnit 3 style:
这允许您指定哪些类构成了相关的测试套件。这相当于 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;
}
}
The equivalent JUnit 4 class will be:
等效的 JUnit 4 类将是:
import org.junit.runners.Suite;
@RunWith(Suite.class)
@SuiteClasses({TestClass1.class, TestClass2.class})
public final class MasterTester {
}
@RunWith(AllTests.class)
@RunWith(AllTests.class)
This allows you to dynamically specify the tests, which compose the test suite. If your tests are not known until runtime, you cannot specify them in the annotations. You can use this construction instead. So, if the JUnit 3 code is:
这允许您动态指定组成测试套件的测试。如果直到运行时才知道您的测试,则无法在注释中指定它们。您可以改用这种结构。所以,如果 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;
}
}
The equivalent JUnit 4 code will be:
等效的 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;
}
}
回答by Andrejs
I've tried this using JUnit 4.8 and it works:
我已经使用 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;
}
}
回答by Maher Abuthraa
Here is a Complete example how to implement that. it combines of two testCase classes and one suite.
这是一个如何实现的完整示例。它结合了两个 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; } }
示例仪器测试:
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; } }
Note that you should use @RunWith(JUnit4.class)
instead of default @RunWith(AndroidJUnit4.class)
in testCase Class
请注意,您应该在 testCase 类中使用@RunWith(JUnit4.class)
而不是默认值@RunWith(AndroidJUnit4.class)