I would like to run all junit 4 tests within my Eclipse project. The project is setup with /source and /test. Under /test are various packages, such as:
com.yaddayadda.test.core.entity
com.yaddayadda.test.core.framework
If I right-click at the /test
level in Package Explorer and choose Run As; Junit Test I receive the error:
No tests found with test runner 'JUnit 4'.
If I right-click on com.yaddayadda.test.core.entity
, then it finds and runs all the tests within that package. So the @Test annotations are correct (they are also picked up by Ant correctly on the build server). However, if I try and run all tests within com.yaddayadda.test.core
then it finds none.
Basically, it only seems to look within the package rather the recusively at all children. Is there a way to fix this?
In order to run all of the tests in a directory including tests in nested directories you will need to use something like googlecode. junittool box. Right clicking on this class and selecting Run As JUnit test runs all of the tests in the specified directory including all tests in nested subfolders. Save this answer.
First: Select your project in Project Explorer and press Alt+Shift+X T. It will run all the JUint tests under the project. The same can be done by right-clicking the project and selecting "Run as"->JUnit test.
If this does not work (which is likely), go to "Run/Run configurations", create a new JUnit configuration and tell it to run all the tests in your project. If this does not work, I'll need to have a look at your project before I can help.
Incase anyone else is looking for a solution to this, I found an answer here on Burt Beckwith's website:
http://burtbeckwith.com/blog/?p=52
To use this, just right-click it in the class tree in Eclipse and click “Run As JUnit Test”.
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Modifier;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.log4j.Logger;
import org.junit.internal.runners.InitializationError;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.Suite;
/**
* Discovers all JUnit tests and runs them in a suite.
*/
@RunWith(AllTests.AllTestsRunner.class)
public final class AllTests {
private static final File CLASSES_DIR = findClassesDir();
private AllTests() {
// static only
}
/**
* Finds and runs tests.
*/
public static class AllTestsRunner extends Suite {
private final Logger _log = Logger.getLogger(getClass());
/**
* Constructor.
*
* @param clazz the suite class - <code>AllTests</code>
* @throws InitializationError if there's a problem
*/
public AllTestsRunner(final Class<?> clazz) throws InitializationError {
super(clazz, findClasses());
}
/**
* {@inheritDoc}
* @see org.junit.runners.Suite#run(org.junit.runner.notification.RunNotifier)
*/
@Override
public void run(final RunNotifier notifier) {
initializeBeforeTests();
notifier.addListener(new RunListener() {
@Override
public void testStarted(final Description description) {
if (_log.isTraceEnabled()) {
_log.trace("Before test " + description.getDisplayName());
}
}
@Override
public void testFinished(final Description description) {
if (_log.isTraceEnabled()) {
_log.trace("After test " + description.getDisplayName());
}
}
});
super.run(notifier);
}
private static Class<?>[] findClasses() {
List<File> classFiles = new ArrayList<File>();
findClasses(classFiles, CLASSES_DIR);
List<Class<?>> classes = convertToClasses(classFiles, CLASSES_DIR);
return classes.toArray(new Class[classes.size()]);
}
private static void initializeBeforeTests() {
// do one-time initialization here
}
private static List<Class<?>> convertToClasses(
final List<File> classFiles, final File classesDir) {
List<Class<?>> classes = new ArrayList<Class<?>>();
for (File file : classFiles) {
if (!file.getName().endsWith("Test.class")) {
continue;
}
String name = file.getPath().substring(classesDir.getPath().length() + 1)
.replace('/', '.')
.replace('\\', '.');
name = name.substring(0, name.length() - 6);
Class<?> c;
try {
c = Class.forName(name);
}
catch (ClassNotFoundException e) {
throw new AssertionError(e);
}
if (!Modifier.isAbstract(c.getModifiers())) {
classes.add(c);
}
}
// sort so we have the same order as Ant
Collections.sort(classes, new Comparator<Class<?>>() {
public int compare(final Class<?> c1, final Class<?> c2) {
return c1.getName().compareTo(c2.getName());
}
});
return classes;
}
private static void findClasses(final List<File> classFiles, final File dir) {
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
findClasses(classFiles, file);
}
else if (file.getName().toLowerCase().endsWith(".class")) {
classFiles.add(file);
}
}
}
}
private static File findClassesDir() {
try {
String path = AllTests.class.getProtectionDomain()
.getCodeSource().getLocation().getFile();
return new File(URLDecoder.decode(path, "UTF-8"));
}
catch (UnsupportedEncodingException impossible) {
// using default encoding, has to exist
throw new AssertionError(impossible);
}
}
}
I found that Burt Beckwith's code is great but it will run every test in the project regardless of where you place AllTests. This modification to one function will allow you to place AllTests in any subdirectory of your project and it will only run tests under that location.
private static Class<?>[] findClasses() {List<File> classFiles = new ArrayList<File>();
String packagepath = AllTests.class.getPackage().getName().replace(".", "/");
File RELATIVE_DIR = new File( CLASSES_DIR.getAbsolutePath() + "\\" + packagepath );
findClasses(classFiles, RELATIVE_DIR);
List<Class<?>> classes = convertToClasses(classFiles, CLASSES_DIR);
return classes.toArray(new Class[classes.size()]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With