Dav*_*Ray 231 java junit unit-testing
在JUnit 3中,我可以得到当前运行的测试的名称,如下所示:
public class MyTest extends TestCase
{
public void testSomething()
{
System.out.println("Current test is " + getName());
...
}
}
Run Code Online (Sandbox Code Playgroud)
这将打印"当前测试是testSomething".
在JUnit 4中是否有任何开箱即用或简单的方法可以做到这一点?
背景:显然,我不想只打印测试的名称.我想加载存储在与测试同名的资源中的特定于测试的数据.你知道,约定优于配置和所有这些.
Fro*_*age 367
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());
}
}
Run Code Online (Sandbox Code Playgroud)
Dun*_*nes 114
从JUnit 4.9开始,TestWatchman该类已被弃用,有利于TestWatcher该类,该类具有调用:
@Rule
public TestRule watcher = new TestWatcher() {
protected void starting(Description description) {
System.out.println("Starting test: " + description.getMethodName());
}
};
Run Code Online (Sandbox Code Playgroud)
以下方法将打印类中所有测试的方法名称:
@Rule
public MethodRule watchman = new TestWatchman() {
public void starting(FrameworkMethod method) {
System.out.println("Starting test: " + method.getName());
}
};
Run Code Online (Sandbox Code Playgroud)
And*_*mov 11
在JUnit 5中有TestInfo注入,它简化了提供测试方法的测试元数据.例如:
@Test
@DisplayName("This is my test")
@Tag("It is my tag")
void test1(TestInfo testInfo) {
assertEquals("This is my test", testInfo.getDisplayName());
assertTrue(testInfo.getTags().contains("It is my tag"));
}
Run Code Online (Sandbox Code Playgroud)
查看更多:JUnit 5用户指南,TestInfo javadoc.
小智 8
考虑使用SLF4J(Simple Logging Facade for Java)使用参数化消息提供了一些巧妙的改进.将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() {
}
}
Run Code Online (Sandbox Code Playgroud)
试试这个:
public class MyTest {
@Rule
public TestName testName = new TestName();
@Rule
public TestWatcher testWatcher = new TestWatcher() {
@Override
protected void starting(final Description description) {
String methodName = description.getMethodName();
String className = description.getClassName();
className = className.substring(className.lastIndexOf('.') + 1);
System.err.println("Starting JUnit-test: " + className + " " + methodName);
}
};
@Test
public void testA() {
assertEquals("testA", testName.getMethodName());
}
@Test
public void testB() {
assertEquals("testB", testName.getMethodName());
}
}
Run Code Online (Sandbox Code Playgroud)
输出如下所示:
Starting JUnit-test: MyTest testA
Starting JUnit-test: MyTest testB
Run Code Online (Sandbox Code Playgroud)
注:此DOES NOT如果你的测试的子类工作的TestCase!测试运行但@Rule代码从未运行过.
一种令人费解的方法是通过继承org.junit.runners.BlockJUnit4ClassRunner来创建自己的Runner.
然后你可以做这样的事情:
public class NameAwareRunner extends BlockJUnit4ClassRunner {
public NameAwareRunner(Class<?> aClass) throws InitializationError {
super(aClass);
}
@Override
protected Statement methodBlock(FrameworkMethod frameworkMethod) {
System.err.println(frameworkMethod.getName());
return super.methodBlock(frameworkMethod);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,对于每个测试类,您需要添加@RunWith(NameAwareRunner.class)注释.或者,如果您不想每次都记住它,可以将该注释放在Test超类上.当然,这限制了您对跑步者的选择,但这可能是可以接受的.
此外,可能需要一点功夫才能将当前的测试名称从Runner和您的框架中获取,但这至少会让您获得名称.
小智 5
String testName = null;
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (int i = trace.length - 1; i > 0; --i) {
StackTraceElement ste = trace[i];
try {
Class<?> cls = Class.forName(ste.getClassName());
Method method = cls.getDeclaredMethod(ste.getMethodName());
Test annotation = method.getAnnotation(Test.class);
if (annotation != null) {
testName = ste.getClassName() + "." + ste.getMethodName();
break;
}
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
}
}
Run Code Online (Sandbox Code Playgroud)