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

后端 未结 6 1937
逝去的感伤
逝去的感伤 2021-02-02 18:13

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

I would like to be able to run the tests on target systems from the application jar, without Eclipse

相关标签:
6条回答
  • 2021-02-02 18:45

    According to a recent thread on the JUnit mailing list, ClasspathSuite can 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.

    0 讨论(0)
  • 2021-02-02 18:45

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

    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.

    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;
            }
        }
    
    }
    
    0 讨论(0)
  • 2021-02-02 19:03

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

    0 讨论(0)
  • 2021-02-02 19:06

    Get the Java project and pass the project

    JUnitLaunchShortcut jUnitLaunchShortcut = new JUnitLaunchShortcut();
    jUnitLaunchShortcut.launch("Pass the Java Project containing JUnits Classes", "run");
    
    0 讨论(0)
  • 2021-02-02 19:09

    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:

    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");
        }
    
    }
    
    0 讨论(0)
  • 2021-02-02 19:09

    I have not tried this as of yet, but came across this blog recently: 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?

    Hope this helps.

    0 讨论(0)
提交回复
热议问题