/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package vogar.target; import com.google.common.base.Function; import com.google.common.base.Functions; import java.util.List; import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; import org.junit.After; import org.junit.Before; import org.junit.Rule; import vogar.Result; import vogar.target.junit.JUnitUtils; import vogar.testing.InterceptOutputStreams; import vogar.testing.InterceptOutputStreams.Stream; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * Provides support for testing {@link TestRunner} class. * *
Subclasses provide the individual test methods, each test method has the following structure. * *
It is annotated with {@link TestRunnerProperties @TestRunnerProperties} that specifies the * properties that the main Vogar process supplies to the client process that actually runs the * tests. It must specify either a {@link TestRunnerProperties#testClass()} or * {@link TestRunnerProperties#testClassOrPackage()}, all the remaining properties are optional. * *
It calls {@code testRunnerRule.createTestRunner(...)} to create a {@link TestRunner}; passing * in any additional command line arguments that {@link TestRunner#TestRunner(Properties, List)} * accepts. * *
It calls {@link TestRunner#run()} to actually run the tests. * *
It calls {@link #expectedResults()} to obtain a {@link ExpectedResults} instance that it uses
* to specify the expected results for the test. Once it has specified the expected results then it
* must call either {@link ExpectedResults#completedNormally()} or
* {@link ExpectedResults#aborted()}. They indicate whether the test process completed normally or
* would abort (due to a test timing out) and cause the actual results to be checked against the
* expected results.
*/
public abstract class AbstractTestRunnerTest {
@Rule
public InterceptOutputStreams ios = new InterceptOutputStreams(Stream.OUT);
@Rule
public TestRunnerRule testRunnerRule = new TestRunnerRule();
/**
* Keeps track of number of times {@link #expectedResults()} has been called without
* {@link ExpectedResults#checkFilteredOutput(String)}
* also being called. If it is {@code > 0} then the test is in error.
*/
private AtomicInteger checkCount;
@Before
public void beforeTest() {
checkCount = new AtomicInteger();
}
@After
public void afterTest() {
if (checkCount.get() != 0) {
throw new IllegalStateException("Test called expectedResults() but failed to call"
+ "either aborted() or completedNormally()");
}
}
protected ExpectedResults expectedResults() {
checkCount.incrementAndGet();
return new ExpectedResults(testRunnerRule.testClass(), ios,
checkCount);
}
protected static class ExpectedResults {
private final StringBuilder builder = new StringBuilder();
private final InterceptOutputStreams ios;
private final AtomicInteger checkCount;
private String testClassName;
private Function