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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17552779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 02:17:44  来源:igfitidea点击:

Record time it takes JUnit tests to run

javajunitload-testing

提问by oneself

I would like to record how long it takes my JUnit test to run programmatically. I have a large number of tests in various test classes, and I would like to find out how long each individual test method takes to run.

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

I can change the inheritance structure or annotate methods differently, but I would like to avoid having to add code within the test method itself and also within the before/after methods which are used to setup test business logic.

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

回答by javaJavaJava

You could use the JUnit StopWatch rule and override its methods as provided in the JUnit API documentation and have the time printed to console or log file for each test just by including one line of code in each of your individual test case class.

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

  1. Create your Customer StopWatch class(Sample provided)

    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. Have a ParentTestClass created with that line and each of your test class inherit the parent test class:

    public class ParentTestCase {
    
    
    @Rule
    public MyJUnitStopWatch stopwatch = new MyJUnitStopWatch();
    
    }
    
  1. 创建您的客户秒表类(提供示例)

    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 并且您的每个测试类都继承父测试类:

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

Child classes inherits parent. No other change in Child classes or before or after methods.

子类继承父类。Child 类或方法之前或之后没有其他变化。

public class TestUniqueCharacterString extends ParentTestCase {    

    private String uniqueChars = null;

    @Before
    public void before(){
        uniqueChars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnop";
    }

    @Test
    public void testMyUniqueCharacterMethod(){


        UniqueCharacteString.doesStringHaveUniqueCharacters(uniqueChars);
    }

Or

或者

  1. Include this line in each of your Test class

    @Rule
    public MyJUnitStopWatch stopwatch = new MyJUnitStopWatch();
    

    Sample Test Class:

    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 = "";
    }    
     }
    
  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 reference:

JUnit API 参考:

http://junit.org/apidocs/org/junit/rules/Stopwatch.html

http://junit.org/apidocs/org/junit/rules/Stopwatch.html

Sample Output

样本输出

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

It will also show time for failed and skipped test cases.

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

回答by Heejin

Try to use @Before and @After. A method annotated with @Before or @After runs before or after the test.

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

    @Before
    public void start() {
        start = System.currentTimeMillis();
    }

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

回答by user3663214

You can also create a @Rule and instantiate the TestWatcher class. This is what worked for me. This is being defined in a class that extends TestCase.

您还可以创建 @Rule 并实例化 TestWatcher 类。这对我有用。这是在扩展 TestCase 的类中定义的。

public class CompositeWithTeardownDBUnitTest extends DBTestCase {

DBTestCase extends TestCase

DBTestCase 扩展了 TestCase

code snippet in CompositeWithTeardownDBUnitTest

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

    }
};

And the JUnit test classes just extend this class CompositeWithTeardownDBUnitTest.

而 JUnit 测试类只是扩展了这个类 CompositeWithTeardownDBUnitTest。

回答by jlogics

Create your own TestWatcherimplementation which catches every test method running. Using Guava Stopwatchyou can measure time for each test:

创建您自己的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));
    }
};

And then add JUnit @Ruleannotation with your TimeTestWatcherfor each test class:

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

public class YourTest {

    @Rule
    public TimeTestWatcher watcher = new TimeTestWatcher();

    @Test
    public void testXXX() {}

    @Test
    public void testYYY() {}
}

回答by Utku ?zdemir

In addition to existing answers, you can use a rule for test name along with Beforeand Aftermethods to display method name on log. Like this:

除了现有答案之外,您还可以使用测试名称规则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
    }
}

Will output:

将输出:

Test foobar took 1828 ms

测试 foobar 耗时 1828 毫秒

回答by cjstehno

You could create a JUnit Rulethat would record the time between before/after calls. This rule could be used as an instance and/or class rule to get you the time for each individual test method as well as for each test class.

您可以创建一个JUnit 规则来记录调用前后之间的时间。此规则可用作实例和/或类规则,以便为每个单独的测试方法以及每个测试类获取时间。

回答by Juned Ahsan

If you use @Before and @After annotations and note the junit testcase start and endtime. Then finding the difference of two timestamps should give you the testcase execution time. Something like this:

如果您使用@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));
    }
 }