如何使用集成测试运行程序在我的 IntelliJ IDEA 项目中运行除以“IntegrationTest”结尾的所有 JUnit 单元测试?

问题描述 投票:0回答:5

我基本上想使用 JUnit 的静态 suite() 方法运行我的 IntelliJ IDEA 项目中的所有 JUnit unit 测试(不包括 JUnit 集成测试)。为什么使用静态 suite() 方法?因为我可以使用 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 中完成此操作,以便我可以使用集成测试运行器 - 我喜欢绿色条:)

java unit-testing reflection junit intellij-idea
5个回答
8
投票

如何将每个主要的 junit 测试组放入自己的根包中。我在我的项目中使用这个包结构:

test.
  quick.
    com.acme
  slow.
    com.acme

无需任何编码,您就可以设置 IntelliJ 来运行所有测试,无论是快速测试还是慢速测试。


7
投票

我已经编写了一些代码来完成大部分工作。仅当您的文件位于本地磁盘而不是 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;
    }
}

5
投票

使用 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 注解来声明不同的测试。

亲切的问候, 蒂莫·迈宁


0
投票

解决方案:https://github.com/MichaelTamm/junit-toolbox
使用以下功能

@RunWith(WildcardPatternSuite.class)
@SuiteClasses({"**/*.class", "!**/*IntegrationTest.class"})
public class AllTestsExceptionIntegrationSuit {
}

假设您遵循集成测试以 ...IntegrationTest 结尾的命名模式,并将文件放置在最顶层的包中(因此 **/*.class 搜索将有机会获取所有测试)


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.