记录JUnit测试运行所需的时间

我想记录我的JUnit测试以编程方式运行需要多长时间。 我在各种测试类中都有大量的测试,我想知道每个测试方法运行多长时间。

我可以不同地更改inheritance结构或注释方法,但我希望避免在测试方法本身以及用于设置测试业务逻辑的before / after方法中添加代码。

尝试使用@Before和@After。 在测试之前或之后运行@Before或@After注释的方法。

@Before public void start() { start = System.currentTimeMillis(); } @After public void end() { System.out.println(System.currentTimeMillis() - start); } 

您可以使用JUnit StopWatch规则并覆盖JUnit API文档中提供的方法,并通过在每个单独的测试用例类中包含一行代码,将时间打印到每个测试的控制台或日志文件中。

  1. 创建您的Customer StopWatch类 (提供示例)

     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); } } 
  2. 使用该行创建ParentTestClass,并且每个测试类都inheritance父测试类:

     public class ParentTestCase { @Rule public MyJUnitStopWatch stopwatch = new MyJUnitStopWatch(); } 

子类inheritance父级。 Child类或方法之前或之后没有其他更改。

 public class TestUniqueCharacterString extends ParentTestCase { private String uniqueChars = null; @Before public void before(){ uniqueChars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnop"; } @Test public void testMyUniqueCharacterMethod(){ UniqueCharacteString.doesStringHaveUniqueCharacters(uniqueChars); } 

要么

  1. 在每个Test类中包含此行

     @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 

它还将显示失败和跳过测试用例的时间。

您还可以创建@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)); } }; 

然后为每个测试类添加带有TimeTestWatcher JUnit @Rule注释:

 public class YourTest { @Rule public TimeTestWatcher watcher = new TimeTestWatcher(); @Test public void testXXX() {} @Test public void testYYY() {} } 

除了现有答案之外,您还可以使用测试名称规则以及BeforeAfter方法在日志中显示方法名称。 喜欢这个:

 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)); } }