View Javadoc
1   package org.junit.rules;
2   
3   import java.util.concurrent.TimeUnit;
4   
5   import org.junit.AssumptionViolatedException;
6   import org.junit.Before;
7   import org.junit.Rule;
8   import org.junit.Test;
9   import org.junit.rules.Stopwatch;
10  import org.junit.runner.Description;
11  import org.junit.runner.JUnitCore;
12  import org.junit.runner.Request;
13  import org.junit.runner.Result;
14  import static java.util.concurrent.TimeUnit.MILLISECONDS;
15  import static org.hamcrest.core.Is.is;
16  import static org.junit.Assert.assertEquals;
17  import static org.junit.Assert.assertThat;
18  import static org.junit.Assume.assumeTrue;
19  import static org.junit.Assert.assertTrue;
20  import static org.junit.Assert.fail;
21  import static org.junit.Assert.assertNotEquals;
22  
23  /**
24   * @author tibor17
25   * @since 4.12
26   */
27  public class StopwatchTest {
28      private static enum TestStatus { SUCCEEDED, FAILED, SKIPPED }
29      private static Record record;
30      private static Record finishedRecord;
31      private static long fakeTimeNanos = 1234;
32  
33      private static class Record {
34          final long duration;
35          final String name;
36          final TestStatus status;
37  
38          Record() {
39              this(0, null, null);
40          }
41  
42          Record(long duration, Description description) {
43              this(duration, null, description);
44          }
45  
46          Record(long duration, TestStatus status, Description description) {
47              this.duration = duration;
48              this.status = status;
49              this.name = description == null ? null : description.getMethodName();
50          }
51      }
52  
53      public static abstract class AbstractStopwatchTest {
54  
55          /**
56           * Fake implementation of {@link Stopwatch.Clock} that increments the time
57           * every time it is asked.
58           */
59          private final Stopwatch.Clock fakeClock = new Stopwatch.Clock() {
60              @Override
61              public long nanoTime() {
62                  return fakeTimeNanos++;
63              }
64          };
65  
66          protected final Stopwatch stopwatch = new Stopwatch(fakeClock) {
67              @Override
68              protected void succeeded(long nanos, Description description) {
69                  StopwatchTest.record = new Record(nanos, TestStatus.SUCCEEDED, description);
70                  simulateTimePassing(1);
71              }
72  
73              @Override
74              protected void failed(long nanos, Throwable e, Description description) {
75                  StopwatchTest.record = new Record(nanos, TestStatus.FAILED, description);
76                  simulateTimePassing(1);
77              }
78  
79              @Override
80              protected void skipped(long nanos, AssumptionViolatedException e, Description description) {
81                  StopwatchTest.record = new Record(nanos, TestStatus.SKIPPED, description);
82                  simulateTimePassing(1);
83              }
84  
85              @Override
86              protected void finished(long nanos, Description description) {
87                  StopwatchTest.finishedRecord = new Record(nanos, description);
88              }
89          };
90  
91          private final TestWatcher watcher = new TestWatcher() {
92              @Override
93              protected void finished(Description description) {
94                  afterStopwatchRule();
95              }
96          };
97  
98          @Rule
99          public final RuleChain chain = RuleChain
100             .outerRule(watcher)
101             .around(stopwatch);
102 
103         protected void afterStopwatchRule() {
104         }
105     }
106 
107     public static class SuccessfulTest extends AbstractStopwatchTest {
108         @Test
109         public void successfulTest() {
110         }
111     }
112 
113     public static class FailedTest extends AbstractStopwatchTest {
114         @Test
115         public void failedTest() {
116             fail();
117         }
118     }
119 
120     public static class SkippedTest extends AbstractStopwatchTest {
121         @Test
122         public void skippedTest() {
123             assumeTrue(false);
124         }
125     }
126 
127     public static class DurationDuringTestTest extends AbstractStopwatchTest {
128         @Test
129         public void duration() {
130             simulateTimePassing(300L);
131             assertEquals(300L, stopwatch.runtime(MILLISECONDS));
132             simulateTimePassing(500L);
133             assertEquals(800L, stopwatch.runtime(MILLISECONDS));
134         }
135     }
136 
137     public static class DurationAfterTestTest extends AbstractStopwatchTest {
138         @Test
139         public void duration() {
140             simulateTimePassing(300L);
141             assertEquals(300L, stopwatch.runtime(MILLISECONDS));
142         }
143 
144         @Override
145         protected void afterStopwatchRule() {
146             assertEquals(300L, stopwatch.runtime(MILLISECONDS));
147             simulateTimePassing(500L);
148             assertEquals(300L, stopwatch.runtime(MILLISECONDS));
149         }
150     }
151 
152     @Before
153     public void init() {
154         record = new Record();
155         finishedRecord = new Record();
156         simulateTimePassing(1L);
157     }
158 
159     private static Result runTest(Class<?> test) {
160         simulateTimePassing(1L);
161         JUnitCore junitCore = new JUnitCore();
162         return junitCore.run(Request.aClass(test).getRunner());
163     }
164 
165     private static void simulateTimePassing(long millis) {
166         fakeTimeNanos += TimeUnit.MILLISECONDS.toNanos(millis);
167     }
168 
169     @Test
170     public void succeeded() {
171         Result result = runTest(SuccessfulTest.class);
172         assertEquals(0, result.getFailureCount());
173         assertThat(record.name, is("successfulTest"));
174         assertThat(record.name, is(finishedRecord.name));
175         assertThat(record.status, is(TestStatus.SUCCEEDED));
176         assertTrue("timeSpent > 0", record.duration > 0);
177         assertThat(record.duration, is(finishedRecord.duration));
178     }
179 
180     @Test
181     public void failed() {
182         Result result = runTest(FailedTest.class);
183         assertEquals(1, result.getFailureCount());
184         assertThat(record.name, is("failedTest"));
185         assertThat(record.name, is(finishedRecord.name));
186         assertThat(record.status, is(TestStatus.FAILED));
187         assertTrue("timeSpent > 0", record.duration > 0);
188         assertThat(record.duration, is(finishedRecord.duration));
189     }
190 
191     @Test
192     public void skipped() {
193         Result result = runTest(SkippedTest.class);
194         assertEquals(0, result.getFailureCount());
195         assertThat(record.name, is("skippedTest"));
196         assertThat(record.name, is(finishedRecord.name));
197         assertThat(record.status, is(TestStatus.SKIPPED));
198         assertTrue("timeSpent > 0", record.duration > 0);
199         assertThat(record.duration, is(finishedRecord.duration));
200     }
201 
202     @Test
203     public void runtimeDuringTestShouldReturnTimeSinceStart() {
204         Result result = runTest(DurationDuringTestTest.class);
205         assertTrue(result.wasSuccessful());
206     }
207 
208   @Test
209     public void runtimeAfterTestShouldReturnRunDuration() {
210         Result result = runTest(DurationAfterTestTest.class);
211         assertTrue(result.wasSuccessful());
212     }
213 }