| package org.junit.rules; |
| |
| import static java.util.concurrent.TimeUnit.MILLISECONDS; |
| import static org.hamcrest.core.Is.is; |
| import static org.hamcrest.MatcherAssert.assertThat; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| import static org.junit.Assume.assumeTrue; |
| |
| import java.util.concurrent.TimeUnit; |
| |
| import org.junit.AssumptionViolatedException; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.runner.Description; |
| import org.junit.runner.JUnitCore; |
| import org.junit.runner.Request; |
| import org.junit.runner.Result; |
| |
| /** |
| * @author tibor17 |
| * @since 4.12 |
| */ |
| public class StopwatchTest { |
| private static enum TestStatus { SUCCEEDED, FAILED, SKIPPED } |
| private static Record record; |
| private static Record finishedRecord; |
| private static long fakeTimeNanos = 1234; |
| |
| private static class Record { |
| final long duration; |
| final String name; |
| final TestStatus status; |
| |
| Record() { |
| this(0, null, null); |
| } |
| |
| Record(long duration, Description description) { |
| this(duration, null, description); |
| } |
| |
| Record(long duration, TestStatus status, Description description) { |
| this.duration = duration; |
| this.status = status; |
| this.name = description == null ? null : description.getMethodName(); |
| } |
| } |
| |
| public abstract static class AbstractStopwatchTest { |
| |
| /** |
| * Fake implementation of {@link Stopwatch.Clock} that increments the time |
| * every time it is asked. |
| */ |
| private final Stopwatch.Clock fakeClock = new Stopwatch.Clock() { |
| @Override |
| public long nanoTime() { |
| return fakeTimeNanos++; |
| } |
| }; |
| |
| protected final Stopwatch stopwatch = new Stopwatch(fakeClock) { |
| @Override |
| protected void succeeded(long nanos, Description description) { |
| StopwatchTest.record = new Record(nanos, TestStatus.SUCCEEDED, description); |
| simulateTimePassing(1); |
| } |
| |
| @Override |
| protected void failed(long nanos, Throwable e, Description description) { |
| StopwatchTest.record = new Record(nanos, TestStatus.FAILED, description); |
| simulateTimePassing(1); |
| } |
| |
| @Override |
| protected void skipped(long nanos, AssumptionViolatedException e, Description description) { |
| StopwatchTest.record = new Record(nanos, TestStatus.SKIPPED, description); |
| simulateTimePassing(1); |
| } |
| |
| @Override |
| protected void finished(long nanos, Description description) { |
| StopwatchTest.finishedRecord = new Record(nanos, description); |
| } |
| }; |
| |
| private final TestWatcher watcher = new TestWatcher() { |
| @Override |
| protected void finished(Description description) { |
| afterStopwatchRule(); |
| } |
| }; |
| |
| @Rule |
| public final RuleChain chain = RuleChain |
| .outerRule(watcher) |
| .around(stopwatch); |
| |
| protected void afterStopwatchRule() { |
| } |
| } |
| |
| public static class SuccessfulTest extends AbstractStopwatchTest { |
| @Test |
| public void successfulTest() { |
| } |
| } |
| |
| public static class FailedTest extends AbstractStopwatchTest { |
| @Test |
| public void failedTest() { |
| fail(); |
| } |
| } |
| |
| public static class SkippedTest extends AbstractStopwatchTest { |
| @Test |
| public void skippedTest() { |
| assumeTrue(false); |
| } |
| } |
| |
| public static class DurationDuringTestTest extends AbstractStopwatchTest { |
| @Test |
| public void duration() { |
| simulateTimePassing(300L); |
| assertEquals(300L, stopwatch.runtime(MILLISECONDS)); |
| simulateTimePassing(500L); |
| assertEquals(800L, stopwatch.runtime(MILLISECONDS)); |
| } |
| } |
| |
| public static class DurationAfterTestTest extends AbstractStopwatchTest { |
| @Test |
| public void duration() { |
| simulateTimePassing(300L); |
| assertEquals(300L, stopwatch.runtime(MILLISECONDS)); |
| } |
| |
| @Override |
| protected void afterStopwatchRule() { |
| assertEquals(300L, stopwatch.runtime(MILLISECONDS)); |
| simulateTimePassing(500L); |
| assertEquals(300L, stopwatch.runtime(MILLISECONDS)); |
| } |
| } |
| |
| @Before |
| public void init() { |
| record = new Record(); |
| finishedRecord = new Record(); |
| simulateTimePassing(1L); |
| } |
| |
| private static Result runTest(Class<?> test) { |
| simulateTimePassing(1L); |
| JUnitCore junitCore = new JUnitCore(); |
| return junitCore.run(Request.aClass(test).getRunner()); |
| } |
| |
| private static void simulateTimePassing(long millis) { |
| fakeTimeNanos += TimeUnit.MILLISECONDS.toNanos(millis); |
| } |
| |
| @Test |
| public void succeeded() { |
| Result result = runTest(SuccessfulTest.class); |
| assertEquals(0, result.getFailureCount()); |
| assertThat(record.name, is("successfulTest")); |
| assertThat(record.name, is(finishedRecord.name)); |
| assertThat(record.status, is(TestStatus.SUCCEEDED)); |
| assertTrue("timeSpent > 0", record.duration > 0); |
| assertThat(record.duration, is(finishedRecord.duration)); |
| } |
| |
| @Test |
| public void failed() { |
| Result result = runTest(FailedTest.class); |
| assertEquals(1, result.getFailureCount()); |
| assertThat(record.name, is("failedTest")); |
| assertThat(record.name, is(finishedRecord.name)); |
| assertThat(record.status, is(TestStatus.FAILED)); |
| assertTrue("timeSpent > 0", record.duration > 0); |
| assertThat(record.duration, is(finishedRecord.duration)); |
| } |
| |
| @Test |
| public void skipped() { |
| Result result = runTest(SkippedTest.class); |
| assertEquals(0, result.getFailureCount()); |
| assertThat(record.name, is("skippedTest")); |
| assertThat(record.name, is(finishedRecord.name)); |
| assertThat(record.status, is(TestStatus.SKIPPED)); |
| assertTrue("timeSpent > 0", record.duration > 0); |
| assertThat(record.duration, is(finishedRecord.duration)); |
| } |
| |
| @Test |
| public void runtimeDuringTestShouldReturnTimeSinceStart() { |
| Result result = runTest(DurationDuringTestTest.class); |
| assertTrue(result.wasSuccessful()); |
| } |
| |
| @Test |
| public void runtimeAfterTestShouldReturnRunDuration() { |
| Result result = runTest(DurationAfterTestTest.class); |
| assertTrue(result.wasSuccessful()); |
| } |
| } |