我想记录我的 JUnit 测试以编程方式运行需要多长时间。我在各种测试类中有大量测试,我想知道每个单独的测试方法需要多长时间才能运行。
我可以更改继承结构或以不同方式注释方法,但我希望避免在测试方法本身以及用于设置测试业务逻辑的之前/之后方法中添加代码。
我想记录我的 JUnit 测试以编程方式运行需要多长时间。我在各种测试类中有大量测试,我想知道每个单独的测试方法需要多长时间才能运行。
我可以更改继承结构或以不同方式注释方法,但我希望避免在测试方法本身以及用于设置测试业务逻辑的之前/之后方法中添加代码。
您可以使用 JUnit StopWatch 规则并覆盖其方法,如 JUnit API 文档中提供的那样,只需在每个单独的测试用例类中包含一行代码,即可将时间打印到每个测试的控制台或日志文件中。
创建您的客户秒表类(提供示例)
import java.util.concurrent.TimeUnit;
import org.junit.AssumptionViolatedException;
import org.junit.rules.Stopwatch;
import org.junit.runner.Description;
public class MyJUnitStopWatch extends Stopwatch{
private static void logInfo(Description description, String status, long nanos) {
String testName = description.getMethodName();
System.out.println(String.format("Test %s %s, spent %d microseconds",
testName, status, TimeUnit.NANOSECONDS.toMicros(nanos)));
}
@Override
protected void succeeded(long nanos, Description description) {
logInfo(description, "succeeded", nanos);
}
@Override
protected void failed(long nanos, Throwable e, Description description) {
logInfo(description, "failed", nanos);
}
@Override
protected void skipped(long nanos, AssumptionViolatedException e, Description description) {
logInfo(description, "skipped", nanos);
}
@Override
protected void finished(long nanos, Description description) {
logInfo(description, "finished", nanos);
}
}
使用该行创建 ParentTestClass,并且每个测试类都继承父测试类:
public class ParentTestCase {
@Rule
public MyJUnitStopWatch stopwatch = new MyJUnitStopWatch();
}
子类继承父类。Child 类或 before 或 after 方法没有其他变化。
public class TestUniqueCharacterString extends ParentTestCase {
private String uniqueChars = null;
@Before
public void before(){
uniqueChars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnop";
}
@Test
public void testMyUniqueCharacterMethod(){
UniqueCharacteString.doesStringHaveUniqueCharacters(uniqueChars);
}
或者
将此行包含在您的每个测试类中
@Rule
public MyJUnitStopWatch stopwatch = new MyJUnitStopWatch();
样本测试类:
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
public class TestUniqueCharacterString {
@Rule
public MyJUnitStopWatch stopwatch = new MyJUnitStopWatch();
private String uniqueChars = null;
@Before
public void before(){
uniqueChars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnop";
}
@Test
public void testMyUniqueCharacterMethod(){
UniqueCharacteString.doesStringHaveUniqueCharacters(uniqueChars);
}
@Test
public void testGoodIsUniqueMethod(){
UniqueCharacteString.isUniqueCharacs(uniqueChars);
}
@Test
public void testGoodIsUniqueMethodWithoutArray(){
UniqueCharacteString.isUniqueCharsWithoutArray(uniqueChars);
}
@After
public void after(){
uniqueChars = "";
}
}
JUnit API 参考:
http://junit.org/apidocs/org/junit/rules/Stopwatch.html
样本输出
Test testMyUniqueCharacterMethod succeeded, spent 3250 microseconds
Test testMyUniqueCharacterMethod finished, spent 3250 microseconds
Test testGoodIsUniqueMethod succeeded, spent 70 microseconds
Test testGoodIsUniqueMethod finished, spent 70 microseconds
Test testGoodIsUniqueMethodWithoutArray succeeded, spent 54 microseconds
Test testGoodIsUniqueMethodWithoutArray finished, spent 54 microseconds
它还将显示失败和跳过的测试用例的时间。
尝试使用@Before 和@After。使用@Before 或@After 注释的方法在测试之前或之后运行。
@Before
public void start() {
start = System.currentTimeMillis();
}
@After
public void end() {
System.out.println(System.currentTimeMillis() - start);
}
您还可以创建 @Rule 并实例化 TestWatcher 类。这对我有用。这是在扩展 TestCase 的类中定义的。
public class CompositeWithTeardownDBUnitTest extends DBTestCase {
DBTestCase 扩展了 TestCase
CompositeWithTeardownDBUnitTest 中的代码片段
@Rule
public TestRule watcher = new TestWatcher() {
protected void starting(Description description) {
timeStart = System.currentTimeMillis();
cal = Calendar.getInstance();
System.out
.println("===========================================================================");
System.out.println("Test: " + description.getMethodName());
System.out.println("Start Time: " + dateFormat.format(cal.getTime()));
System.out
.println("===========================================================================");
}
protected void finished(Description description) {
timeEnd = System.currentTimeMillis();
double seconds = (timeEnd-timeStart)/1000.0;
System.out
.println("\n===========================================================================");
System.out
.println("Test completed - ran in: "+new DecimalFormat("0.000").format(seconds)+" sec");
System.out
.println("===========================================================================\n");
}
};
JUnit 测试类只是扩展了这个类 CompositeWithTeardownDBUnitTest。
创建您自己的TestWatcher
实现来捕获每个运行的测试方法。使用 Guava Stopwatch
,您可以测量每个测试的时间:
public class TimeTestWatcher extends TestWatcher {
private Stopwatch stopwatch = Stopwatch.createUnstarted();
protected void starting(Description description) {
stopwatch.start();
}
protected void finished(Description description) {
stopwatch.stop();
String testName = description.getMethodName();
long elapsed = stopwatch.elapsed(TimeUnit.MILLISECONDS);
System.out.println(String.format("Test %s took %d ms.", testName, elapsed));
}
};
然后为每个测试类添加 JUnit@Rule
注释:TimeTestWatcher
public class YourTest {
@Rule
public TimeTestWatcher watcher = new TimeTestWatcher();
@Test
public void testXXX() {}
@Test
public void testYYY() {}
}
除了现有答案之外,您还可以使用测试名称规则Before
以及After
方法在日志上显示方法名称。像这样:
public class ImageSavingTest {
@Rule
public TestName name = new TestName();
private long start;
@Before
public void start() {
start = System.currentTimeMillis();
}
@After
public void end() {
System.out.println("Test " + name.getMethodName() + " took " + (System.currentTimeMillis() - start) + " ms");
}
@Test
public void foobar() {
// test code here
}
}
将输出:
测试 foobar 耗时 1828 毫秒
您可以创建一个JUnit 规则来记录调用前后的时间。该规则可以用作实例和/或类规则,以获取每个单独的测试方法以及每个测试类的时间。
如果您使用 @Before 和 @After 注释并注意 junit 测试用例的开始和结束时间。然后找到两个时间戳的差异应该会给你测试用例的执行时间。像这样的东西:
public class Example {
long startTime;
long endTime;
@Before public void recordStartTime() {
startTime = System.currentTimeMillis();
}
@Test public void testSomething() {
//test method
}
@After public void recordEndAndExecutionTime() {
endTime = System.currentTimeMillis();
System.out.println("Last testcase exection time in millisecond : " + (endTime - startTime));
}
}