在JUnit 3中,我可以像这样获得当前运行的测试的名称:

public class MyTest extends TestCase
{
    public void testSomething()
    {
        System.out.println("Current test is " + getName());
        ...
    }
}

它会打印“当前测试是testSomething”。

在JUnit 4中是否有任何开箱即用或简单的方法来做到这一点?

背景:显然,我不想只打印测试的名称。我希望加载存储在与测试同名的资源中的特定于测试的数据。你知道,约定比配置更重要。


当前回答

考虑使用SLF4J (Java的简单日志Facade)使用参数化消息提供了一些整洁的改进。将SLF4J与JUnit 4规则实现相结合可以提供更有效的测试类日志记录技术。

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.rules.TestWatchman;
import org.junit.runners.model.FrameworkMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LoggingTest {

  @Rule public MethodRule watchman = new TestWatchman() {
    public void starting(FrameworkMethod method) {
      logger.info("{} being run...", method.getName());
    }
  };

  final Logger logger =
    LoggerFactory.getLogger(LoggingTest.class);

  @Test
  public void testA() {

  }

  @Test
  public void testB() {

  }
}

其他回答

JUnit 4.9。X及以上

从JUnit 4.9开始,TestWatchman类已经被弃用,取而代之的是TestWatcher类,它有以下调用:

@Rule
public TestRule watcher = new TestWatcher() {
   protected void starting(Description description) {
      System.out.println("Starting test: " + description.getMethodName());
   }
};

注意:包含类必须声明为public。

JUnit 4.7。X - 4.8.x

下面的方法将打印类中所有测试的方法名称:

@Rule
public MethodRule watchman = new TestWatchman() {
   public void starting(FrameworkMethod method) {
      System.out.println("Starting test: " + method.getName());
   }
};

I'd suggest you decouple the test method name from your test data set. I would model a DataLoaderFactory class which loads/caches the sets of test data from your resources, and then in your test case cam call some interface method which returns a set of test data for the test case. Having the test data tied to the test method name assumes the test data can only be used once, where in most case i'd suggest that the same test data in uses in multiple tests to verify various aspects of your business logic.

基于前面的评论,并进一步考虑我创建了一个TestWather的扩展,你可以在你的JUnit测试方法中使用:

public class ImportUtilsTest {
    private static final Logger LOGGER = Logger.getLogger(ImportUtilsTest.class);

    @Rule
    public TestWatcher testWatcher = new JUnitHelper(LOGGER);

    @Test
    public test1(){
    ...
    }
}

测试助手类是下一个:

public class JUnitHelper extends TestWatcher {
private Logger LOGGER;

public JUnitHelper(Logger LOGGER) {
    this.LOGGER = LOGGER;
}

@Override
protected void starting(final Description description) {
    LOGGER.info("STARTED " + description.getMethodName());
}

@Override
protected void succeeded(Description description) {
    LOGGER.info("SUCCESSFUL " + description.getMethodName());
}

@Override
protected void failed(Throwable e, Description description) {
    LOGGER.error("FAILURE " + description.getMethodName());
}
}

享受吧!

JUnit 5通过ExtensionContext

优势:

您可以通过重写afterEach(ExtensionContext上下文)来获得ExtensionContext的附加功能。

public abstract class BaseTest {

    protected WebDriver driver;

    @RegisterExtension
    AfterEachExtension afterEachExtension = new AfterEachExtension();

    @BeforeEach
    public void beforeEach() {
        // Initialise driver
    }

    @AfterEach
    public void afterEach() {
        afterEachExtension.setDriver(driver);
    }

}
public class AfterEachExtension implements AfterEachCallback {

    private WebDriver driver;

    public void setDriver(WebDriver driver) {
        this.driver = driver;
    }

    @Override
    public void afterEach(ExtensionContext context) {
        String testMethodName = context.getTestMethod().orElseThrow().getName();
        // Attach test steps, attach scsreenshots on failure only, etc.
        driver.quit();
    }

}

JUnit 4.7似乎使用TestName-Rule添加了这个特性。看起来这将为您提供方法名称:

import org.junit.Rule;

public class NameRuleTest {
    @Rule public TestName name = new TestName();

    @Test public void testA() {
        assertEquals("testA", name.getMethodName());
    }

    @Test public void testB() {
        assertEquals("testB", name.getMethodName());
    }
}