我们使用JUnit 4进行测试:我们不都是一个子类类TestCase
,并且他们有注解的公共方法@Test
。 我们有一个文件有许多@Test
方法。 这将是很好能够通过Ant在命令行中运行它们的一个子集,在这几招JUnit 3中的风格:
ant runtest -Dtest=MyTest -Dtests=testFoo,testBar
http://today.java.net/pub/a/today/2003/09/12/individual-test-cases.html
我一直在努力想办法实现这个与Java反射等。因为似乎没有被任何方式来“隐藏” @Test
方法或删除在运行时的批注,唯一的选择似乎是使用类加载器的defineClass
方法,这似乎是相当困难的。
PS正确的事情在这种情况下将分割的文件,但有没有办法?
谢谢你的时间。
由于JUnit的4.8,我们有@Category注解来解决这一点问题。
guerda的解决方案是好的。 下面是我落得这样做(这是卢克Francl的食谱,这是我之前链接,以及其他一些东西,我在网上看到的混合):
import org.junit.runner.manipulation.Filter;
import org.junit.runner.Description;
public final class AntCLFilter extends Filter {
private static final String TEST_CASES = "tests";
private static final String ANT_PROPERTY = "${tests}";
private static final String DELIMITER = "\\,";
private String[] testCaseNames;
public AntCLFilter() {
super();
if (hasTestCases()) testCaseNames = getTestCaseNames();
}
public String describe() {
return "Filters out all tests not explicitly named in a comma-delimited list in the system property 'tests'.";
}
public boolean shouldRun(Description d) {
String displayName = d.getDisplayName();
// cut off the method name:
String testName = displayName.substring(0, displayName.indexOf('('));
if (testCaseNames == null) return true;
for (int i = 0; i < testCaseNames.length; i++)
if (testName.equals(testCaseNames[i]))
return true;
return false;
}
/**
* Check to see if the test cases property is set. Ignores Ant's
* default setting for the property (or null to be on the safe side).
**/
public static boolean hasTestCases() {
return
System.getProperty( TEST_CASES ) == null ||
System.getProperty( TEST_CASES ).equals( ANT_PROPERTY ) ?
false : true;
}
/**
* Create a List of String names of test cases specified in the
* JVM property in comma-separated format.
*
* @return a List of String test case names
*
* @throws NullPointerException if the TEST_CASES property
* isn't set
**/
private static String[] getTestCaseNames() {
if ( System.getProperty( TEST_CASES ) == null ) {
throw new NullPointerException( "Test case property is not set" );
}
String testCases = System.getProperty( TEST_CASES );
String[] cases = testCases.split(DELIMITER);
return cases;
}
}
import org.junit.internal.runners.*;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.NoTestsRemainException;
public class FilteredRunner extends TestClassRunner {
public FilteredRunner(Class<?> clazz) throws InitializationError {
super(clazz);
Filter f = new AntCLFilter();
try {
f.apply(this);
} catch (NoTestsRemainException ex) {
throw new RuntimeException(ex);
}
}
}
然后,我注解我的测试类:
@RunWith(FilteredRunner.class)
public class MyTest {
并加入下面的我的Ant构建:
<target name="runtest"
description="Runs the test you specify on the command line with -Dtest="
depends="compile, ensure-test-name">
<junit printsummary="withOutAndErr" fork="yes">
<sysproperty key="tests" value="${tests}" />
<classpath refid="classpath" />
<formatter type="plain" usefile="false" />
<batchtest>
<fileset dir="${src}">
<include name="**/${test}.java" />
</fileset>
</batchtest>
</junit>
</target>
重点线有作为sysproperty标签。
现在我可以运行
ant runtest -Dtest=MyTest -Dtests=testFoo,testBar
如预期的。 这个工程使用JUnit 4.1 --- 4.4,从子类JUnit4ClassRunner,并在4.5及更高版本,从BlockJUnit4ClassRunner子类。
创建您自己的TestClassMethodsRunner
(它没有任何声明或我现在不觉得它)。
一个TestClassMethodsRunner
执行所有的TestCase你可以设置一个过滤TestClassMethodsRunner
。
所有你需要做的就是重写TestMethodRunner createMethodRunner(Object, Method, RunNotifier)
方法。 这是一个简单的解决方案哈克:
public class FilteredTestRunner extends TestClassMethodsRunner {
public FilteredTestRunner(Class<?> aClass) {
super(aClass);
}
@Override
protected TestMethodRunner createMethodRunner(Object aTest, Method aMethod, RunNotifier aNotifier) {
if (aTest.getClass().getName().contains("NOT")) {
return new TestMethodRunner(aTest, aMethod, aNotifier, null) {
@Override
public void run() {
//do nothing with this test.
}
};
} else {
return super.createMethodRunner(aTest, aMethod, aNotifier);
}
}
}
有了这个TestRunner的,你执行不包含字符串“NOT”所有测试。 其他人将被忽略:)只需添加@RunWith
与你的TestRunner类注释您的测试。
@RunWith(FilteredTestRunner.class)
public class ThisTestsWillNOTBeExecuted {
//No test is executed.
}
@RunWith(FilteredTestRunner.class)
public class ThisTestsWillBeExecuted {
//All tests are executed.
}
在createMethodRunner
方法,你可以对证的必须执行或引入新的规定-测试列表当前测试。
祝你好运与此!
对于一个更好的解决方案提示的感谢!
这里是你需要只运行一个测试方法,而不必去通过创建自定义的麻烦通常情况下一个简单的方法Runner
或Filter
:
public class MyTestClass {
public static void main(final String[] args) throws Exception {
final JUnitCore junit = new JUnitCore();
final String singleTest = // Get the name of test from somewhere (environment, system property, whatever you want).
final Request req;
if (singleTest != null) {
req = Request.method(MyTestClass.class, singleTest);
} else {
req = Request.aClass(MyTestClass.class);
}
final Result result = junit.run(req);
// Check result.getFailures etc.
if (!result.wasSuccessful()) {
System.exit(1);
}
}
// Your @Test methods here.
}