blob: 5941eb9b1bb129037b7efec0e320b601b2d78521 [file] [log] [blame]
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());
}
}