我基本上想在我的IntelliJ IDEA项目中运行所有JUnit单元测试(不包括JUnit集成测试),使用JUnit的静态suite()方法。为什么要使用staticsuite()方法?因为我可以使用IntelliJ IDEA的JUnit测试运行程序来运行我的应用程序中的所有单元测试(并通过命名约定轻松排除所有集成测试)。到目前为止,代码如下:
package com.acme;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class AllUnitTests extends TestCase {
public static Test suite() {
List classes = getUnitTestClasses();
return createTestSuite(classes);
}
private static List getUnitTestClasses() {
List classes = new ArrayList();
classes.add(CalculatorTest.class);
return classes;
}
private static TestSuite createTestSuite(List allClasses) {
TestSuite suite = new TestSuite("All Unit Tests");
for (Iterator i = allClasses.iterator(); i.hasNext();) {
suite.addTestSuite((Class<? extends TestCase>) i.next());
}
return suite;
}
}
方法getUnitTestClasses()应该重写以添加所有扩展TestCase的项目类,除非类名以"IntegrationTest"结尾。
例如,我知道我可以在Maven中轻松完成这项工作,但我需要在IntelliJ IDEA中完成,这样我才能使用集成的测试运行程序-我喜欢绿色条:)
将每个主要的junit测试组放入它们自己的根包中如何。我在我的项目中使用这个包结构:
test.
quick.
com.acme
slow.
com.acme
在没有任何编码的情况下,您可以设置IntelliJ来运行所有测试,无论是快速测试还是慢速测试。
我已经编写了一些代码来完成大部分工作。只有当您的文件在本地磁盘上而不是在JAR中时,它才能工作。你只需要包里的一个类。为此,您可以创建一个Locator.java类,以便能够找到包。
public class ClassEnumerator {
public static void main(String[] args) throws ClassNotFoundException {
List<Class<?>> list = listClassesInSamePackage(Locator.class, true);
System.out.println(list);
}
private static List<Class<?>> listClassesInSamePackage(Class<?> locator, boolean includeLocator)
throws ClassNotFoundException {
File packageFile = getPackageFile(locator);
String ignore = includeLocator ? null : locator.getSimpleName() + ".class";
return toClassList(locator.getPackage().getName(), listClassNames(packageFile, ignore));
}
private static File getPackageFile(Class<?> locator) {
URL url = locator.getClassLoader().getResource(locator.getName().replace(".", "/") + ".class");
if (url == null) {
throw new RuntimeException("Cannot locate " + Locator.class.getName());
}
try {
return new File(url.toURI()).getParentFile();
}
catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
private static String[] listClassNames(File packageFile, final String ignore) {
return packageFile.list(new FilenameFilter(){
@Override
public boolean accept(File dir, String name) {
if (name.equals(ignore)) {
return false;
}
return name.endsWith(".class");
}
});
}
private static List<Class<?>> toClassList(String packageName, String[] classNames)
throws ClassNotFoundException {
List<Class<?>> result = new ArrayList<Class<?>>(classNames.length);
for (String className : classNames) {
// Strip the .class
String simpleName = className.substring(0, className.length() - 6);
result.add(Class.forName(packageName + "." + simpleName));
}
return result;
}
}
使用JUnit4和Suite Runner怎么样?
示例:
@RunWith(Suite.class)
@Suite.SuiteClasses({
UserUnitTest.class,
AnotherUnitTest.class
})
public class UnitTestSuite {}
我制作了一个小的Shell脚本来查找所有的单元测试,并制作了另一个来查找我的集成测试。看看我的博客:http://blog.timomeinen.de/2010/02/find-all-junit-tests-in-a-project/
如果使用Spring TestContext,则可以使用@IfProfile Annotation来声明不同的测试。
谨致问候,Timo Meinen
Spring在PathMatchingResourcePatternResolver中实现了出色的类路径搜索功能。如果使用classpath*:前缀,则可以查找所有资源,包括给定层次结构中的类,甚至可以根据需要对它们进行筛选。然后,您可以使用AbstractTypeHierarchyTraversingFilter、AnnotationTypeFilter和AssignableTypeFilter的子级在类级注释或它们实现的接口上过滤这些资源。
http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/core/io/support/PathMatchingResourcePatternResolver.html
http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/core/type/filter/AbstractTypeHierarchyTraversingFilter.html
解决方案:https://github.com/MichaelTamm/junit-toolbox
使用以下功能
@RunWith(WildcardPatternSuite.class)
@SuiteClasses({"**/*.class", "!**/*IntegrationTest.class"})
public class AllTestsExceptionIntegrationSuit {
}
假设您遵循一种命名模式,其中集成测试以…结束。。。IntegrationTest,然后将文件放在最上面的包中(因此**/*.class搜索将有机会获取所有测试)