[ 
https://issues.apache.org/jira/browse/JENA-380?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13755681#comment-13755681
 ] 

Claude Warren commented on JENA-380:
------------------------------------


I have been working on migrating the unit tests to JUnit4.11 and think I have a 
design that works and meets the requirements/goals stated above.

My strategy for building the new Junit 4.11 tests is:
1. Tag the source tree and check it out.
2. Migrate all tests from Junit 3.x to 4.11 while moving them to packages that 
match the packages of the class under test.
3. For interfaces the tests must take a parameter so that implementers can 
easily run/extended the standard tests against their implementation.
4. For complex interfaces (e.g. ones that return other interfaces defined in 
Jena) test suites must be constructed that will test all of the returned 
interface.
5. Reuse the classes implemented for current testing where appropriate (e.g. 
com.hp.hpl.jena.graph.RecordingListener)
6. Mock classes for which a testing implementation does not currently exist 
where required. (e.g. a mock TransactionHandler ).
7. Diff the tag of the current trunk (assuming that new tests have been added)
8. Add new tests to account for the diff.
9. Repeat 7 through 9 until there are no changes.
10. Work with development team to ensure orderly transition to new tests.
11. possibly redo steps 7 through 9 to account for any possibly missed changes.
12. Document how to extend the classes to make life easier for implementers.

I have not tagged the source tree yet and am looking through the existing tests 
to ensure that I understand how to convert the patterns that have been used to 
the 4.11 version.  To that end I have the following (also in the README in the 
new-test branch at /src/test/java/com/hp/hpl/jena/graph)

Interface tests are built so that developers may test that implementations meet 
the contract
set out in the interface and accompanying documentation.

The major items under test use an instance of the GraphProducerInterface to 
create the graph
being tested.  An implementation of  GraphProducerInterface must track all the 
tests created
during the test and close all of them when requested.  There is an 
AbstractGrapProducer that 
handles most of that functionality but requires a createNewGraph() 
implementation.

TESTS
=====

Interface tests are noted as Abstract(INTERFACENAME)Test.  Tests generally 
extend the 
AbstractGraphProducerUser class.  This class handles cleaning up all the graphs 
at the end of 
the tests and provides a hook for implementers to plug in their 
GraphProducerInterface.

In general to implement a test requires a few lines of code as is noted in the 
example below
where the new Foo graph implementation is being tested.

<code>
public class FooGraphTest extends AbstractGraphTest {

        // the graph producer to use while running
        GraphProducerInterface graphProducer = new FooGraphTest.GraphProducer();

        @Override
        protected GraphProducerInterface getGraphProducer() {
                return graphProducer;
        }
        
        // the implementation of the graph producer.
        public static class GraphProducer extends AbstractGraphProducer {
                @Override
                protected Graph createNewGraph() {
                        return new FooGraph();
                }
        }

}
</code>

SUITES
======

Test suites are named as Abstract(INTERFACENAME)Suite.  Suites contain several 
tests that 
excersize all of the tests for the components of the object under test.  For 
example the graph
suite includes tests for the graph iteself, the reifier, finding literals, 
recursive subgraph
extraction, event manager, and transactions.  Running the suites is a bit more 
complicated then
running the tests.

Suites are created using the JUnit 4 @RunWith(Suite.class) and  
@Suite.SuiteClasses({ })
annotations.  This has several effects that the developer should know about:
1. The suite class does not get instantiated during the run.
2. The test class names must be known at coding time (not run time) as they are 
listed in the
        annotation.
3. Configuration of the tests has to occur during the static initialization 
phase of class 
        loading.
        
To meet these requirements the AbstractGraphSuite has a static variable that 
holds the instance
of the GraphProducerInterface and a number of local static implementations of 
the Abstract tests that 
implement the "getGraphProducer()" method by returning the static instance.  
The names of the 
local graphs are then used in the @Suite.SuiteClasses annotation.  This makes 
creating an 
instance of the AbstractGraphSuite for a graph implementation fairly simple as 
is noted below.

<code>
public class FooGraphSuite extends AbstractGraphSuite {

        @BeforeClass
        public static void beforeClass() {
                setGraphProducer(new GraphProducer());
        }

        public static class GraphProducer extends AbstractGraphProducer {
                @Override
                protected Graph createNewGraph() {
                        return new FooGraph();
                }
        }

}
</code>

Note that the beforeClass() method is annotated with @BeforeClass.  the 
@BeforeClass causes it to be run once before any of the test methods in the 
class. This will set the static
instance of the graph producer before the suite is run so that it is provided 
to the enclosed
tests. 
                
> Migrate core tests to junit4
> ----------------------------
>
>                 Key: JENA-380
>                 URL: https://issues.apache.org/jira/browse/JENA-380
>             Project: Apache Jena
>          Issue Type: Task
>          Components: Jena
>    Affects Versions: Jena 2.10.0
>            Reporter: Claude Warren
>            Assignee: Claude Warren
>            Priority: Minor
>
> Many of the tests for jena core are junit3 suites.  I would like to start a 
> process of migrating them to junit 4 and rework them so that when compiling 
> in the Eclipse IDE clicking on the failed test will take you to the failed 
> test while maintaining the current test names.  I would expect some test 
> names to change based upon changes in functionality.
> The goals of this change are :
> 1) Move to junit 4
> 2) Ensure that when the entire package is run as a junit test all tests 
> succeed. (i.e. valid default tests)
> 3) Continue to provide test classes that can be utilized by implementers of 
> interfaces.
> 4) Extract utility/helper code into utility/helper classes to simplify the 
> test inheritance tree.
> 5) Move the test classes into the same package name as the classes they test. 
>  Currently we have x.foo for the implementation classes and x.foo.test for 
> the test classes.
> The process would be:
> 1) build a number of sub tasks under this change to deliver smaller changes.  
> The smaller changes will be based on the package names and that can be 
> delivered incrementally.
> 2) once all tests are in junit4 perform a sweep across the test code base 
> looking for any junit 3 classes that remain.  Verify that their testing 
> functionality has been replaced by other code and remove them.
> The result will be a complete review of all the core tests and a migration to 
> junit 4 and annotated tests.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to