eclipse 如何以编程方式在我的 Java 应用程序中运行所有 JUnit 测试?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2411938/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 14:29:57  来源:igfitidea点击:

How do I programmatically run all the JUnit tests in my Java application?

javaeclipsejunitjunit4

提问by Andrew McKinlay

From Eclipse I can easily run all the JUnit tests in my application.

在 Eclipse 中,我可以轻松地在我的应用程序中运行所有 JUnit 测试。

I would like to be able to run the tests on target systems from the application jar, without Eclipse (or Ant or Maven or any other development tool).

我希望能够从应用程序 jar 在目标系统上运行测试,而无需 Eclipse(或 Ant 或 Maven 或任何其他开发工具)。

I can see how to run a specific test or suite from the command line.

我可以看到如何从命令行运行特定的测试或套件。

I could manually create a suite listing all the tests in my application, but that seems error prone - I'm sure at some point I'll create a test and forget to add it to the suite.

我可以手动创建一个套件,列出我的应用程序中的所有测试,但这似乎很容易出错 - 我确信在某个时候我会创建一个测试并忘记将它添加到套件中。

The Eclipse JUnit plugin has a wizard to create a test suite, but for some reason it doesn't "see" my test classes. It may be looking for JUnit 3 tests, not JUnit 4 annotated tests.

Eclipse JUnit 插件有一个创建测试套件的向导,但由于某种原因它没有“看到”我的测试类。它可能正在寻找 JUnit 3 测试,而不是 JUnit 4 注释测试。

I could write a tool that would automatically create the suite by scanning the source files.

我可以编写一个工具,通过扫描源文件自动创建套件。

Or I could write code so the application would scan it's own jar file for tests (either by naming convention or by looking for the @Test annotation).

或者我可以编写代码,以便应用程序扫描它自己的 jar 文件以进行测试(通过命名约定或通过查找 @Test 注释)。

It seems like there should be an easier way. What am I missing?

似乎应该有更简单的方法。我错过了什么?

采纳答案by Andrew McKinlay

I ran into a minor problem with my last solution. If I ran "all tests" from Eclipse they ran twice because they ran the individual tests AND the suite. I could have worked around that, but then I realized there was a simpler solution:

我的上一个解决方案遇到了一个小问题。如果我从 Eclipse 运行“所有测试”,它们会运行两次,因为它们运行了单独的测试和套件。我本来可以解决这个问题的,但后来我意识到有一个更简单的解决方案:

package suneido;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class RunAllTests {

    public static void run(String jarfile) {
        String[] tests = findTests(jarfile);
        org.junit.runner.JUnitCore.main(tests);
    }

    private static String[] findTests(String jarfile) {
        ArrayList<String> tests = new ArrayList<String>();
        try {
            JarFile jf = new JarFile(jarfile);
            for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements();) {
                String name = e.nextElement().getName();
                if (name.startsWith("suneido/") && name.endsWith("Test.class")
                        && !name.contains("$"))
                    tests.add(name.replaceAll("/", ".")
                            .substring(0, name.length() - 6));
            }
            jf.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return tests.toArray(new String[0]);
    }

    public static void main(String[] args) {
        run("jsuneido.jar");
    }

}

回答by Brett Daniel

According to a recent threadon the JUnit mailing list, ClasspathSuitecan collect and run all JUnit tests on the classpath. It is not precisely what you want, since it is a class-level annotation, but the source is available, so you may be able to extend its internal discovery mechanism.

根据最近JUnit 邮件列表上的一个线程ClasspathSuite可以收集和运行类路径上的所有 JUnit 测试。它不是您想要的,因为它是类级别的注释,但源可用,因此您可以扩展其内部发现机制。

回答by Andrew McKinlay

Based on http://burtbeckwith.com/blog/?p=52I came up with the following. It seems to work well.

基于http://burtbeckwith.com/blog/?p=52我想出了以下内容。它似乎运作良好。

I can run it from within my code with:

我可以从我的代码中运行它:

org.junit.runner.JUnitCore.main("suneido.AllTestsSuite");

One weak point is that it relies on a naming convention ("Test" suffix) to identify tests. Another weak point is that the name of the jar file is hard coded.

一个弱点是它依赖命名约定(“Test”后缀)来识别测试。另一个弱点是 jar 文件的名称是硬编码的。

package suneido;

import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;

/**
 * Discovers all JUnit tests in a jar file and runs them in a suite.
 */
@RunWith(AllTestsSuite.AllTestsRunner.class)
public final class AllTestsSuite {
    private final static String JARFILE = "jsuneido.jar";

    private AllTestsSuite() {
    }

    public static class AllTestsRunner extends Suite {

        public AllTestsRunner(final Class<?> clazz) throws InitializationError {
            super(clazz, findClasses());
        }

        private static Class<?>[] findClasses() {
            List<String> classFiles = new ArrayList<String>();
            findClasses(classFiles);
            List<Class<?>> classes = convertToClasses(classFiles);
            return classes.toArray(new Class[classes.size()]);
        }

        private static void findClasses(final List<String> classFiles) {
            JarFile jf;
            try {
                jf = new JarFile(JARFILE);
                for (Enumeration<JarEntry> e = jf.entries(); e.hasMoreElements();) {
                    String name = e.nextElement().getName();
                    if (name.startsWith("suneido/") && name.endsWith("Test.class")
                            && !name.contains("$"))
                        classFiles.add(name.replaceAll("/", ".")
                                .substring(0, name.length() - 6));
                }
                jf.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        private static List<Class<?>> convertToClasses(
                final List<String> classFiles) {
            List<Class<?>> classes = new ArrayList<Class<?>>();
            for (String name : classFiles) {
                Class<?> c;
                try {
                    c = Class.forName(name);
                }
                catch (ClassNotFoundException e) {
                    throw new AssertionError(e);
                }
                if (!Modifier.isAbstract(c.getModifiers())) {
                    classes.add(c);
                }
            }
            return classes;
        }
    }

}

回答by rhinds

I have not tried this as of yet, but came across this blog recently: http://burtbeckwith.com/blog/?p=52

我还没有尝试过,但最近看到了这个博客:http: //burtbeckwith.com/blog/?p=52

The author provides a class that discovers all your junits and runs them, so if you slot this in to your project it may provide the capability required?

作者提供了一个发现所有junit 并运行它们的类,所以如果您将它插入到您的项目中,它可能会提供所需的功能?

Hope this helps.

希望这可以帮助。

回答by Karthiekyan

Get the Java project and pass the project

获取Java项目并通过项目

JUnitLaunchShortcut jUnitLaunchShortcut = new JUnitLaunchShortcut();
jUnitLaunchShortcut.launch("Pass the Java Project containing JUnits Classes", "run");

回答by u290629

You also could use ANTwhich has built-in task. Write ANT script and run it on target machine. ANT could create report as result.

您也可以使用具有内置任务的ANT。编写 ANT 脚本并在目标机器上运行它。ANT 可以创建报告作为结果。