History log of /external/vogar/src/vogar/target/junit/DescribableComparator.java
Revision Date Author Comments (<<< Hide modified files) (Show modified files >>>)
dfd9233635dd8752272fbeba22ffb88183ce300a 26-Mar-2016 Paul Duffin <paulduffin@google.com> Use JUnit classes for running JUnit3 tests

Removes the custom code for handling JUnit3 classes and switches
to use standard JUnit classes, albeit heavily customised.

Some classes were removed because they are no longer used.
src/vogar/target/junit/ConfigurationError.java
src/vogar/target/junit/VogarTest.java
src/vogar/target/junit/VogarTestRunner.java
src/vogar/target/junit/VogarTestRunnerBuilder.java

JUnit 3 tests come from three different types of classes:
1) A class that extends TestCase
2) A class that implements Test; but does not extend TestCase
3) A class that has a method that looks like this (it can return
any type that extends Test).
public static Test suite()

Vogar does not support type #2. It also does not support type #3
where the classes in the Test hierarchy returned by the suite()
method contains anything other than type #1 or type #3 tests.

The JUnit 4 support for running JUnit 3 classes cannot be used
because it behaves differently to Vogar, i.e.
* It supports type #2 above; that would cause problems were
Vogar starts running tests that it did not run before.
* It creates the test instances during test discovery rather
than at test runtime like it does with JUnit 4 classes and
like Vogar does with both JUnit 3 and JUnit 4 classes.
* It produces meaningless errors when it finds a problem with a
TestCase, e.g. a test method not being public. In that case
it reports the problem as being with test
junit.framework.TestSuite$1#warning even though it obviously
is not.

In order to preserve Vogar's existing behavior it was necessary
to replace a few parts of JUnit's behavior. That is very similar
to what is done in AndroidJUnitRunner so the intent is in future
to make these changes more widely usable, possibly even by
pushing to JUnit itself.

Type #1 test classes are handled in JUnit by the TestSuite class
which constructs a TestSuite from a TestCase based class, that
involves scanning the class to find the test methods and then
constructing the TestCase instances that are encapsulated within
the TestSuite object. The TestSuite class is passed to a
JUnit38ClassRunner which bridges between JUnit 3 testing
classes, e.g. TestResult, TestListener and JUnit 4 testing
classes, e.g. Runner, RunNotifier.

In Vogar type #1 test classes are handled by the following:
TestCaseTransformer<S, T> - this is responsible for scanning a
TestCase based class to find the test methods, creating
a list of instances of T for each test method, sorting the
list and then creating an instance of S for the suite as a
whole which encapsulates the list.
The construction of T and S is delegated to the supplied
TestCaseFactory<S, T> instance.
The sort order is determined by the supplied
Comparator<? super T>.
TestCaseFactory<S, T> - is an interface that provides support
for creating test objects T for each test method and suite
objects S for the whole test suite.
TestCaseRunnerFactory - is an implementation of
TestCaseFactory<Runner, DescribableStatement>. Each test
method is represented by a DescribableStatement, the suite
is represented as a Runner.
AlternateTestCaseBuilder - this is the RunnerBuilder
implementation that integrates the above into the JUnit
RunnerBuilder infrastructure.

All of the above are useful standalone (when taken with their
supporting classes), they could be taken and reused as they
stand. There are some Vogar specific extension classes that
add some Vogar specific capabilities that are not generally
useful:
VogarTestCaseRunnerFactory - extends TestCaseRunnerFactory to
add support for explicitly requested methods.
VogarTestCaseBuilder - extends AlternateTestCaseBuilder to
provide it with an instance of VogarTestCaseRunnerFactory
instead of its default TestCaseRunnerFactory instance.

This pattern of separating out the scanning from the
representation/creation makes the code much more flexible and
reusable. e.g. If this code was ported back into JUnit then it
would be possible for TestSuite to be reimplemented in terms
of TestCaseTransformer simply by providing a suitable
TestCaseFactory<TestSuite, TestCase> implementation.

Type #3 test classes are handled in JUnit 4 by
SuiteMethodBuilder which checks to see if the method has a
suite() method and if it does it invokes it and then wraps the
resulting Test object in a JUnit38ClassRunner instance. It
relies on the recursion code in TestSuite to traverse the
hierarchy of Test objects.

In Vogar type #3 test classes are handled by the following:
TestSuiteTransformer<T> - it traverses a hierarchy of Test
objects and transforms them into a hierarchy of T objects.
The construction of the various classes of T objects are
delegated to the supplied TestSuiteFactory<T> instance.
TestSuiteFactory<T> - is an interface that provides support
for creating suite, test case and custom instances of type
T.
TestSuiteRunnerFactory is an implementation of
TestSuiteFactory<Runner>, where suites are represented as
a Suite (actually an ExtendedSuiteRunner), test cases are
represented as StatementRunner and custom tests as
ErrorRunner because they are not supported.
AlternateSuiteMethodBuilder - this is the RunnerBuilder
implementation that integrates the above into the JUnit
RunnerBuilder infrastructure used by Vogar.

The remaining changes are support classes needed for the above.

Test: Build vogar-tests and run them,
run art/tools/run-libcore-tests.sh

Bug: 27940141
Change-Id: I9acf9fa49a3da7d0bc2f82334b9f1f8b6924a099
/external/vogar/src/vogar/target/junit/DescribableComparator.java