确定junit的业务相关代码的执行时间的最佳做法是什么?

Ste*_*ike 18 java junit

在eclipse-> junit-view中显示的测试执行时间取决于整个测试用例执行,包括:

  • Testdata准备
  • 执行businesslogic
  • 断言结果

我需要一个关于businesslogic的执行时间和我的businesslogic的更详细的声明.这就是我在我的测试用例中所做的:

Date lNow = new Date();
List<Geo> lAllBasisGeo = mGeoEvaluator.evaluateAllGeo(lGeoFixture.getGeo(), lAllGeo);
Date lStop = new Date();
System.out.println("Time of execution in seconds:"+((lStop.getTime()-lNow.getTime())/1000));
Run Code Online (Sandbox Code Playgroud)

好吧......我想我确定时间很尴尬.此外,我不认为有必要声明两个Date变量.

我需要更有效地编写代码的建议......

Sim*_*ant 28

在单元测试中,我更倾向于使用JUnit 4注释向Test添加超时,以确定测试是否通过(足够快):

@Test(timeout=100)//let the test fail after 100 MilliSeconds
public void infinity() {
  while(true);
}
Run Code Online (Sandbox Code Playgroud)

要确定业务逻辑的确切运行时间,我会像你一样在关键Codepath之前和之后添加Time语句,重复几次以获得学术上正确的结果,并再次删除语句,以便减少代码.

long start = System.currentTimeMillis();
//execute logic in between
long end = System.currentTimeMillis();
System.out.println("DEBUG: Logic A took " + (end - start) + " MilliSeconds");
Run Code Online (Sandbox Code Playgroud)


acd*_*ior 24

JUnit 4.12介绍了Stopwatch @Rule.它使用起来非常困难,应该成为验证测试期间花费的时间的事实方法.这是一个展示其功能的示例类:

public static class StopwatchTest {
     private static final Logger logger = Logger.getLogger("");

     private static void logInfo(Description description, String status, long nanos) {
         String testName = description.getMethodName();
         logger.info(String.format("Test %s %s, spent %d microseconds",
                                   testName, status, TimeUnit.NANOSECONDS.toMicros(nanos)));
     }

     @Rule
     public Stopwatch stopwatch = new Stopwatch() {
         @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);
         }
     };

     @Test
     public void succeeds() {
     }

     @Test
     public void fails() {
         fail();
     }

     @Test
     public void skips() {
         assumeTrue(false);
     }

     @Test
     public void performanceTest() throws InterruptedException {
         // An example to assert runtime:
         long delta = 30;
         Thread.sleep(300L);
         assertEquals(300d, stopwatch.runtime(MILLISECONDS), delta);
         Thread.sleep(500L);
         assertEquals(800d, stopwatch.runtime(MILLISECONDS), delta);
     }
}
Run Code Online (Sandbox Code Playgroud)

  • @AndyDufresne不幸的是,我不认为你只能使用规则测量测试方法.发生这种情况是因为JUnit的`@ Rule`s机制不允许规则做出这样的区分(他们甚至不知道`@ Before`s的存在).我建议你在所有之前的一个字段中记录`stopwatch.runtime(MILLISECONDS)`(在课程结束时放置一个,因为它应该最后执行),然后从测量的时间中减去它.(如果你有一个`@ After`,那应该在那里计算.) (2认同)

Bor*_*der 12

在Guava库中有一个非常有用的实用工具 - 秒表.
这将允许您编写以下内容

import com.google.common.base.Stopwatch;

final Stopwatch stopwatch = Stopwatch.createStarted();
//dostuff
System.out.println("Time of execution in seconds:" + stopwatch.stop().elapsed(TimeUnit.SECONDS));
Run Code Online (Sandbox Code Playgroud)

  • 遗憾的是,我没有使用第三方库的许可. (2认同)