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/VogarTestCaseRunnerFactory.java
|