33

I want to be able to run all tests in a project programmatically. I know Eclipse has a "Run as JUnit test" configuration which somehow grabs all the tests in a project and run them. Is there any way for me to also grab the list of tests programmatically and run them? Or is there some good way to construct a test suite containing all the test cases without manually listing out every one (all 700+) of them?

I've tried the "New... -> Test Suite" option in Eclipse, but that seems to work only for JUnit 3, identifying tests by their extending from TestCase

The test classes are JUnit 4, so their only distinguishing characteristic is the annotation, no naming convention, no subclassing from TestCase.

Thanks in advance!

alexloh
  • 1,606
  • 2
  • 15
  • 29

7 Answers7

23

Though it does not really solve your immediate problem, I find it a very useful general practice to create suites and suites of suites, e.g. for a package something like PackageFooSuite etc. and assemble these suites in one or more suites again, like ModuleFooSuite and have one top-level suite, like AllTestsSuite. That way it's easy to run both all tests in one step as well as submodule tests for the package I'm currently working on (and have the tests run quicker than if I would always run all of them):

@RunWith(Suite.class)
@Suite.SuiteClasses({ PackageFooSuite.class, PackageBarSuite.class} )
public final class AllTestsSuite {} // or ModuleFooSuite, and that in AllTests
Fabian Steeg
  • 44,988
  • 7
  • 85
  • 112
  • 1
    I tend to agree with you. Unfortunately the people who were working on this before me did not and left maybe 700 or more testcases which I am not keen on manually stringing together by hand – alexloh Feb 12 '10 at 21:54
  • @alexloh: Yeah, quite understandable. Perhaps it's actually feasible to automate this without too much hassle, like: for each package/directory, create a suite class made of the names of all the files in the current package/directory. If you start from the bottom directory, it might also be relatively simple to include the generated suites for a sub-package in the level above. – Fabian Steeg Feb 12 '10 at 22:06
16

None of the other answers did it for me. I had 40k tests I needed to run, so manually listing every class was not an option.

I did it with ClasspathSuite. A test suite that runs all Junit4 and Junit3 test cases in the class path is as follows:

import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.extensions.cpsuite.ClasspathSuite.*;
import org.junit.runner.RunWith;
import org.junit.runner.JUnitCore;
import static org.junit.extensions.cpsuite.SuiteType.*;

@RunWith(ClasspathSuite.class)
@SuiteTypes({ JUNIT38_TEST_CLASSES, TEST_CLASSES })
public class RunAllSuite {
        /* main method not needed, but I use it to run the tests */
        public static void main(String args[]) {
                JUnitCore.runClasses(RunAllSuite.class);
        }
}

I needed to run it from command line, so this is what I did:

  1. Downloaded cp-1.2.6.jar
  2. Create the previously mentioned RunAllSuite
  3. Compile the class, javac RunAllSuite.java -cp cpsuite-1.2.6.jar;junit-4.8.1.jar
  4. run it with target tests in the class path, java -cp cpsuite-1.2.6.jar;junit-4.8.1.jar;path/to/runallsuite/folder;target/classes;target/test-classes RunAllSuite

And that's it. With the RunAllSuite above, anywhere in your code you can just do JUnitCore.runClasses(RunAllSuite.class), which runs all tests in class path. There are other config options as well which are explained in the ClasspathSuite home page.

Note also that the class given above does not print anything. If that is needed, you can do

import org.junit.extensions.cpsuite.ClasspathSuite;
import org.junit.extensions.cpsuite.ClasspathSuite.*;
import org.junit.runner.RunWith;
import org.junit.runner.JUnitCore;
import org.junit.internal.TextListener;
import static org.junit.extensions.cpsuite.SuiteType.*;

@RunWith(ClasspathSuite.class)
@SuiteTypes({ JUNIT38_TEST_CLASSES, TEST_CLASSES })
public class RunAllSuite {
        public static void main(String args[]) {
                JUnitCore junit = new JUnitCore();
                junit.addListener(new TextListener(System.out));
                junit.run(RunAllSuite.class);
        }
}
eis
  • 51,991
  • 13
  • 150
  • 199
  • "I had 40k tests I needed to run, so manually listing every class was not an option." Could you have used some sort of text manipulation program to scan the names of these test class files and create the code to run the test? That is, for each .java file, print a line in the RunAllSuite class that says `JUnitCore.main( $thatfilename.class );` -- not that your code doesn't work already. – Jan Feb 19 '16 at 04:39
  • 2
    @Jan even if we put aside the impracticality, size of the class has its limits as well (64k characters, to be exact). I don't see how all those test names would've fit that. – eis Feb 19 '16 at 09:10
  • ah, good point. I didn't know that there was a hard limit! Besides, your solution is very elegant already! – Jan Feb 19 '16 at 17:26
3

You can do this fairly easily from within maven using the surefire plugin: I usually clean/compile/install my projects from the command line before comparing them for eclipse usage (mvn eclipse:clean eclipse:eclipse) and you can define a test suite in your pom which lists all the tests you want to run en masse every time you run mvn install. You're not calling them programatically, exactly, but you can certainly call them en masse.

davek
  • 22,499
  • 9
  • 75
  • 95
  • Hmm... I don't use Maven, but I'll try it out if it solves my problem. I'll tick this if I find that it works. Thanks!! – alexloh Feb 12 '10 at 21:56
2

In Eclipse (I'm using 4.6.1) - Right click the project folder, select "Run As", choose "JUnit Test"

It will run all tests in that project. Same for a package.

Carlos Rendon
  • 6,174
  • 5
  • 34
  • 50
1

Of the top of my head using Spring:

  • Implement a TypeFilter that matches classes with methods annotated with @Test (don't forget to consider the superclasses)
  • Invoke classpath scanning on your top-most test package
  • Invoke the JUnitRunner with the scan results

More info on classpath scanning and custom type filters here

Axel Fontaine
  • 34,542
  • 16
  • 106
  • 137
0

With Eclipse Indigo (possibly Helios as well) in the Run Configurations dialog box, you now have the ability to Run all tests in a selected project, package or source folder.

Also a good reference from Eclipse is the article Java Unit testing with JUnit 4.x in Eclipse.

Mookie Wilson
  • 188
  • 2
  • 10
-1

I also recommend using the JUnit Suite annotations. Follow the link for more detail.

Community
  • 1
  • 1
cmcginty
  • 113,384
  • 42
  • 163
  • 163