6

我想在我的 Eclipse 项目中运行所有 junit 4 测试。该项目是使用 /source 和 /test 设置的。/test 下面是各种包,例如:

com.yaddayadda.test.core.entity
com.yaddayadda.test.core.framework

如果我右键单击/test包资源管理器中的级别并选择运行方式;Junit 测试我收到错误:

No tests found with test runner 'JUnit 4'.

如果我右键单击com.yaddayadda.test.core.entity,它会找到并运行该包中的所有测试。所以 @Test 注释是正确的(它们也被 Ant 在构建服务器上正确拾取)。但是,如果我尝试在其中运行所有测试,com.yaddayadda.test.core则找不到。

基本上,它似乎只在包装内看,而不是在所有孩子身上回避。有没有办法解决这个问题?

4

4 回答 4

8

首先:在 Project Explorer 中选择您的项目,然后按 Alt+Shift+X T。它将运行项目下的所有 JUint 测试。同样可以通过右键单击项目并选择“运行为”->JUnit 测试来完成。

如果这不起作用(很可能),请转到“运行/运行配置”,创建一个新的 JUnit 配置并告诉它运行项目中的所有测试。如果这不起作用,我需要先查看您的项目,然后才能提供帮助。

于 2010-09-15T18:01:17.270 回答
5

万一其他人正在寻找解决方案,我在 Burt Beckwith 的网站上找到了答案:

http://burtbeckwith.com/blog/?p=52

要使用它,只需在 Eclipse 的类树中右键单击它,然后单击“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);
    }
  }
}
于 2011-03-21T04:28:54.660 回答
1

我发现 Burt Beckwith 的代码很棒,但无论您将 AllTests 放在哪里,它都会运行项目中的每个测试。对一个函数的这种修改将允许您将 AllTests 放在项目的任何子目录中,并且它只会在该位置下运行测试。

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()]);
}
于 2017-07-07T06:27:38.257 回答
0

您是否添加/test到构建路径 -> 源文件夹?

于 2010-09-17T08:26:07.617 回答