Run all tests in Junit 4 - java

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!

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

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:
Downloaded cp-1.2.6.jar
Create the previously mentioned RunAllSuite
Compile the class, javac RunAllSuite.java -cp cpsuite-1.2.6.jar;junit-4.8.1.jar
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);
}
}

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.

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.

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

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.

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

Related

How to make a bat file and test with it a JUnit4 Test Suite without Eclipse but with Command Line?

I finished my two projects, one is a real one, and the other simulates a server that just generates some data, and now i made a junit test suite to test it both and all works.
Now is the time to send the real project together with the tests to a friend that made the real server project, that generates real data.
So I need now to prepare the tests somehow so he can just run them on Command Line, but I have no idea how to do that.
I searched a little on the net, and there was no way to run a test suite from the command line...and I hope you can help me.
Here is what I have in the test project:
The class AllTests is a test suite, from witch I can run all the tests listed in it:
package test.dss;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({
TestAddAndDeleteScript.class,
TestEnumerateScripts.class,
TestEnumerateTemplates.class,
TestExecute.class,
TestGetAllImportsList.class,
TestGetBindings.class,
TestGetSource.class,
TestGetTemplate.class,
TestLogin.class,
TestLogout.class,
TestOpenAndCloseFile.class,
TestReloadLastLog.class,
TestSetDates.class,
TestSetPatientList.class,
TestStartStopTimer.class,
TestUpdateBindingParameters.class,
TestUpdateScript.class,
TestUpdateSharedUserList.class,
TestUpdateTextArea.class
})
public class AllTests {
}
Then there are the tests that are for the other project:
With a similar code in the AllTests class:
package test.mw;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({
TestEnumerateParams.class,
TestEnumeratePatients.class, // za properties, pogledati red 55
TestEnumerateScripts.class,
TestGetAll.class,
TestGetResults.class,
TestLogin.class,
TestLogout.class,
TestRaiseAlarm.class,
TestRegisterUnregisterScript.class,
TestSaveResult.class
})
public class AllTests {
}
Now, I removed the tests from the workspace, and placed it on the desktop and have to figure out how to test it in command line, while my two projects run in elipse on localhost.
On top, I wanna create a BAT file witch my friend can just run (from the command line) and test his part (the mw part).
Yeah, I forgot to mention, all the jars I need to run the tests are in the JRE System Library, JUnit 4 and referenced Libraries that are from the lib folder.
So, I created a CMD Tests folder on the desktop, and copied all the files from the tests, and it looks like this:
So here are the two parts of my question:
a) How to test them all at once with the two test suites?
a.b) If there is no way, how to test each class individually?
b) How to make a bat file to run it all at once?
Please help.
There is no need to create two test suites if you want to test them together. Just place all of the test classes into single Suite.
But running tests from two suites will look somehow like this:
java -cp "lib/*;bin" org.junit.runner.JUnitCore test.dss.AllTests test.mv.AllTests
Just place a .bat file in the root of your project with this content and you're ready to go.
You can also use the same command for running a particular test, means something like:
java -cp "lib/*;bin" org.junit.runner.JUnitCore test.dss.TestExecute
Note: I don't know how you compile your classes. I guess all of them are in bin folder. If they are not just add the appropriate folder to the -cp section.

Finding all tests in a subpackage

When I try running JUnit tests, I get the error message
No tests found with test runner 'JUnit 4'
and therefore I have tried solutions from
No tests found with test runner 'JUnit 4'
junit: no tests found
'No JUnit tests found' in Eclipse
However, in my case, the difference seems to be that I specify the tests to run on package level instead of folder level.
Running JUnit tests works if I specify a package that directly contains test classes (e.g. com.example.tests.smoketests) but does not work if a higher level package is specified (e.g. com.example.tests).
If I define a test in com.example.tests, it is found and run.
Is there a way to let Eclipse/JUnit find tests in a package and all subpackages?
Out of the box, there is nothing to do this for you. You can use the Suite annotation to achieve this goal in JUnit4, though this still requires you to manually define a Suite test for each package, and then include all of them in a aggregate Suite test (such they recursively call child Suites).
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import a.sub.package.AnotherSuiteTest.class;
#RunWith(Suite.class)
#Suite.SuiteClasses({
PackageLocalTestClass1.class,
PackageLocalTestClass2.class,
AnotherSuiteTest.class
})
public class JunitTestSuite {
}
I've played around with building my own utility class before which creates the entire series of tests. This article provides an analogous utility.

Running testing class from jar package in NetBeans

I have like 30 Java classes and 1 class for testing in a jar package.
To run the testing class, I need to create new NetBeans project , import all those 30 classes into /src , then import 1 testing class into /test and maybe add some libraries to the project also...
So that, after all I will be able to run the testing class...
Is there some other way to do it?
I open the jar package in NetBeans and see all the classes but it doesn't let me run the testing class since there is no main method in there..
A bunch of ways. If you're in NetBeans, and the class has a public static void main() method you can just right-click it and choose Run File.
But you're far better off writing your test as a JUnit or TestNG test - that way it is not included in your production bits, and continuous build tools and other things will be able to run your tests automatically because they look the way those tools expect.

Run JUnit tests from a dependency jar in Eclipse

I have some JUnit tests that contained in a .jar that is intended to be used as a library. The library contains some tests that should be run whenever the library is used in another project.
However when I create a new project using the library and run JUnit on it in Eclipse then the tests in the dependency .jar don't run / don't get detected by the JUnit test runner. I get the message:
No tests found with test runner 'JUnit 4'.
Is there a way I can configure the dependency .jar so that the tests will run alongside any tests that might be contained in the main project?
Basically I want the dependency .jar to "export" the tests to whatever projects it is used in.
I'm using Eclipse Juno, JUnit 4.10, and Maven for the dependency management.
EDIT:
The point of this library is to be able to help test projects that use it - i.e. it runs some specialised tests. This is why I want to be able to import the library .jar and have it contribute the extra tests to the importing project.
You can try Maven Surefire.
In some cases it would be useful to have a set of tests that run with various dependency configurations. One way to accomplish this would be to have a single project that contains the unit tests and generates a test jar. Several test configuration projects could then consume the unit tests and run them with different dependency sets. The problem is that there is no easy way to run tests in a dependency jar. The Surefire plugin should have a configuration to allow me to run all or a set of unit tests contained in a dependency jar.
This can be done as follows (Junit 3):
Ensure test jar contains a class which has a static suite() method
import junit.framework.Test;
import junit.framework.TestSuite;
public class AllTests {
public static Test suite()
{
TestSuite suite = new TestSuite( "All Tests");
suite.addTestSuite(TestOne.class);
suite.addTestSuite(TestTwo.class);
return suite;
}
}
Then in the project using the test-jar dependency:
create a TestCase:
package org.melati.example.contacts;
import org.melati.poem.AllExportedTests;
import junit.framework.Test;
import junit.framework.TestCase;
public class PoemTest extends TestCase {
public static Test suite()
{
return AllExportedTests.suite();
}
}
Now the tests will be found.
I think that making a library of unit tests (#Test annotated methods) is a bad idea. However, making a library of reusable test components is a good one. We've done this in a few open source projects, and you can take a look how it works.
One Maven module exports test components (we call them "mocks"), from src/mock/java directory. Exported artifact has -mock classifier. See rexsl/pom.xml (pay attention to highlighted lines).
Mock artifacts are being deployed to Maven Central, together with usual artifacts: http://repo1.maven.org/maven2/com/rexsl/rexsl-core/0.3.8/ (pay attention to ...-mock.jar files)
Modules that need that mocks can include them as usual artifacts, for example rexsl-core/pom.xml (see highlighted lines):
Then, in your unit tests just use the classes from that mock libraries, like regular builders of mocks, for example: BulkHttpFeederTest
That's how you can make your test artifacts reusable, in an elegant way. Hope it helps.
#Mikera,
I find that this may help you. Just extend the Testcase Class to one of your java classes in project and you can run that particular class to run it as a JUnit Test.
I am not sure that this is desirable - On the one hand, if you use a jar, its behaviour might be influenced by the external context, e.g. other libraries in the classpath. From inside the jar, there is no simple way to analyse this context and to adjust the tests accordingly. On the other hand, if you write and compile a library, you should test it before packaging it as a jar. You might even want to not include your tests.
If it is really important to you to run the tests again, I would be interested in what could make them fail without changing the jar. In that case, however, you might want to extend the testrunner. As far as I know it uses reflection. You can quite easily load jars in a classloader and go through all their classes. By reflection you can identify the test classes and assemble testsuites. You could look into the testrunner for an example. Still, you would need to start this process from outside, e.g. from inside one of your test classes in the client project. Here, QATest's approach might be helpful: By providing an overriden version of testsuite or testrunner, you could automate this - if the client uses your overridden API.
Let me know if this rather costly approach seems to be applicable in your scenario and I can provide code examples.
Why should the user of the jar run the test cases inside the jar!!! When the jar is packaged and delivered, it means that the unit tests are run successfully.
Typically, the jar itself should be either treated as a separate project or as one of the modules. In both the cases, unit test cases are run before its delivered.

Why does the "Run as jUnit Test" not show up for existing classes in Eclipse?

I'm having problems running methods as a jUnit in Eclipse. I know how to do so in Eclipse on my Mac and now I'm trying to get it to work on Ubuntu 12.04.
Normally, if you have a method like...
#Test
public void foo(){}
...you can right-click the foo method and one of the options is "Run as jUnit Test". Since I started attempting to use jUnit test in Eclipse on my Ubuntu machine, I see this option when I define a method in a brand new class. For example, I created a brand new class with the method test1:
package all;
import org.junit.Test;
public class BabyClass {
#Test
public void test1(){}
}
Right-clicking on test1 gives me the "Run as jUnit Test" option and the jUnit test works as expected.
However, if I go into one of my older classes (from before I ever tried using jUnit) and try to run a method as a jUnit test by right-clicking on its name, then the run as jUnit test option isn't there, which is puzzling. The "old" and "new" classes are all in the same package, in case that is relevant to know.
Does anyone have any ideas why the option to run as a jUnit test is not appearing for methods in my older classes? Is there something I'm supposed to do to make the option appear? This seems kind of like a bug in Eclipse to me.
Thanks.
You can't do jUnit tests with classes that involve generics.
package all;
import org.junit.Test;
public class BabyClass<T> {
#Test
public void test1(){
}
}
The baby class is now parameterized, but you can't do a jUnit test with it any more.

Categories