Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I recursively find and run all Junit 4 tests within Eclipse?

Tags:

junit4

eclipse

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?

like image 393
WW. Avatar asked Sep 10 '10 01:09

WW.


People also ask

How do I run all JUnit tests at once?

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.


3 Answers

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.

like image 64
Andrey Breslav Avatar answered Sep 28 '22 19:09

Andrey Breslav


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);
    }
  }
}
like image 40
WW. Avatar answered Sep 28 '22 19:09

WW.


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()]);
}
like image 28
Mykro Avatar answered Sep 28 '22 20:09

Mykro