运行JUnit @Test方法的子集
问题内容:
我们正在使用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
在运行时“隐藏”
方法或删除其注释,因此唯一的选择似乎是使用ClassLoader的defineClass
方法,这似乎相当困难。
PS在这种情况下正确的事情是将文件分割开,但是还有其他选择吗?
谢谢你的时间。
问题答案:
guerda的解决方案很好。这就是我最终要做的事情(这是我以前联系过的卢克·弗朗克食谱的混合物,还有我在网上看到的其他东西):
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 buildfile中:
<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的子类。