You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Claude Warren <cl...@xenei.com> on 2017/01/28 10:08:37 UTC

RDF commons testing

I see that RDF Commons is listed as a set of interfaces to be implemented
on top of various RDF implementations.  I also see that there are abstract
tests for the interfaces.

I would like to suggest that RDF commons look at using Junit Contract tests
(https://github.com/Claudenw/junit-contracts) which will ensure that tests
for all the implemented interfaces are run against the implementing classes.

The strategy for junit-contracts is to create interface tests into which an
instance of the object being tested is injected.  Implementation test
suites are created by declaring the class under test and a mechanism to
create the instance of the class.  The contract-test junit runner then
locates all tests for all interfaces that are implemented by the class
under test and runs them (A dynamic suite if you will).

As interface tests are developed they are automatically picked up by the
suites.  As interfaces are implemented by classes the suites automatically
pick up existing tests.  The maven plugins (and command line tools) will
report on the interfaces that don't have tests as well as classes that
don't have tests suites defined.

Besides the convenience of the system finding the tests to run this
strategy has several other advantages:

1.  It allows classes that implement multiple interfaces to have one test
that tests them all.  Developers no longer have to track down abstract test
classes across multiple projects and create concrete implementations.

2.  It allows developers to quickly determine if their implementation
matches the full contract for the interface.

3.  It means that refactoring of parent interfaces / classes do not force
additional coding for the testing of derived classes.

If you are interested I would be glad to help convert existing tests to
contract tests.

Claude
-- 
I like: Like Like - The likeliest place on the web
<http://like-like.xenei.com>
LinkedIn: http://www.linkedin.com/in/claudewarren

Re: RDF commons testing

Posted by Sergio Fernández <wi...@apache.org>.
Thanks for the suggestion, Claude!

I agree with Stian, do a PR with how the test suite would change, so then
we are discussing about more concrete things.

On Mon, Jan 30, 2017 at 11:20 AM, Stian Soiland-Reyes <st...@apache.org>
wrote:

> On Mon, 30 Jan 2017 09:08:27 +1100, Peter Ansell <an...@gmail.com>
> wrote:
> > Hi Claude,
> > Abstract test classes are working well for Commons RDF so far. Others
> > may benefit from your solution, so feel free to suggest the approach
> > to others who may be interested in exploring it.
>
> I would not dismiss Claude's suggestion out of hand. Apache Commons is
> for anyone who wants to participate! :-)
>
> Claude  - if you would like to have a go in a branch at what Commons RDF
> tests look like using contract testing, then feel free!
>
> >> https://www.linkedin.com/pulse/contract-testing-why-
> abstract-tests-enough-claude-warren-jr
>
> I liked this blog article which explains the problem. We in a way
> already have this problem twice in Commons RDF tests because we have the
> Triple/Quad duality (TripleLike) and Graph/Dataset duality (GraphLike)
> as well as the multiple implementations of the commons-rdf-api
> interfaces.
>
> So you will notice some of those tests have considerable duplication
> with subtle differences, e.g. along the lines of:
>
>
>     graph.add(triple);
>     assertTrue(graph.contains(triple)
>     assertTrue(graph.contains(triple.getSubject(),
>         triple.getPredicate(), triple.getObject());
>
> vs
>
>     dataset.add(quad);
>     assertTrue(dataset.contains(quad));
>     assertTrue(dataset.contains(quad.getGraphName(),
>       quad.getSubject(), quad.getPredicate(), quad.getObject());
>
> This could in theory be harmonized so that there's a single abstract
> test class with an abstract method to make the triple/quad - and then
> extensions for Triple and Quad that adds the last decomposition
> assertion.
>
> But as we already use abstract classes to run the tests per RDF
> implementation, and so I thought it would get messy to try to reorganize
> it.
>
>
> Another thing is that now the tests are munged together
> into mainly AbstractRDFTest (which must create an RDF factory instance,
> that then can create the other things) - otherwise you will have to
> make many SomethingImplTest in each module (and easily forget to
> specialize one of the tests in one of the modules)
>
> With your approach, would you still have to make a such specialization,
> or is that automatic?
>
>
> BTW - in your approach, would it work to run the tests out of the box
> from an IDE like Eclipse? I think that is quite important so Commons RDF
> can be maintainable by many people in Apache Commons.
>
>
>
>
> --
> Stian Soiland-Reyes
> University of Manchester
> http://www.esciencelab.org.uk/
> http://orcid.org/0000-0001-9842-9718
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>


-- 
Sergio Fernández
Partner Technology Manager
Redlink GmbH
m: +43 6602747925
e: sergio.fernandez@redlink.co
w: http://redlink.co

Re: RDF commons testing

Posted by Stian Soiland-Reyes <st...@apache.org>.
On Mon, 30 Jan 2017 10:20:46 +0000, Stian Soiland-Reyes <st...@apache.org> wrote:
> BTW - in your approach, would it work to run the tests out of the box 
> from an IDE like Eclipse? I think that is quite important so Commons RDF
> can be maintainable by many people in Apache Commons.

They did run out of the box in Eclipse thanks to the @TestRunner, and it
looks quite nice, separated out per interface contract tested:

https://raw.githubusercontent.com/stain/junit-contracts/patch-1/docs/junit-contracts.png


I was confused by your examples still using test class hierarchy like
"BarTest extends FooTest" which then turns out to be not needed at all.
Also I don't think there's generally a need to use the confusing
indirection of IProducer but rather give the instance to be tested
directly.

I was confused with @Contract.Inject being the annotation both for
the property to be set and the factory method to generate the
implementaton.


I added a suggestion to your README to show how junit-contracts can be
used with multiple interfaces and multiple implementations, using
java.util.Set as an example which I think many on this list will 
be familiar with.

https://github.com/stain/junit-contracts/tree/patch-1#motivation

I also think the ability to have different @Before is a strong
argument - so this could be relevant in multiple project with
several interface implementaton, but also for Commons RDF.


-- 
Stian Soiland-Reyes
http://orcid.org/0000-0001-9842-9718


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: RDF commons testing

Posted by Stian Soiland-Reyes <st...@apache.org>.
On Mon, 30 Jan 2017 09:08:27 +1100, Peter Ansell <an...@gmail.com> wrote:
> Hi Claude,
> Abstract test classes are working well for Commons RDF so far. Others
> may benefit from your solution, so feel free to suggest the approach
> to others who may be interested in exploring it.

I would not dismiss Claude's suggestion out of hand. Apache Commons is
for anyone who wants to participate! :-)

Claude  - if you would like to have a go in a branch at what Commons RDF
tests look like using contract testing, then feel free!

>> https://www.linkedin.com/pulse/contract-testing-why-abstract-tests-enough-claude-warren-jr

I liked this blog article which explains the problem. We in a way
already have this problem twice in Commons RDF tests because we have the
Triple/Quad duality (TripleLike) and Graph/Dataset duality (GraphLike)
as well as the multiple implementations of the commons-rdf-api
interfaces.

So you will notice some of those tests have considerable duplication
with subtle differences, e.g. along the lines of:


    graph.add(triple);
    assertTrue(graph.contains(triple)
    assertTrue(graph.contains(triple.getSubject(),
        triple.getPredicate(), triple.getObject());

vs

    dataset.add(quad);
    assertTrue(dataset.contains(quad));
    assertTrue(dataset.contains(quad.getGraphName(),
      quad.getSubject(), quad.getPredicate(), quad.getObject());

This could in theory be harmonized so that there's a single abstract
test class with an abstract method to make the triple/quad - and then
extensions for Triple and Quad that adds the last decomposition
assertion.

But as we already use abstract classes to run the tests per RDF
implementation, and so I thought it would get messy to try to reorganize
it.


Another thing is that now the tests are munged together
into mainly AbstractRDFTest (which must create an RDF factory instance,
that then can create the other things) - otherwise you will have to
make many SomethingImplTest in each module (and easily forget to
specialize one of the tests in one of the modules)

With your approach, would you still have to make a such specialization,
or is that automatic?


BTW - in your approach, would it work to run the tests out of the box 
from an IDE like Eclipse? I think that is quite important so Commons RDF
can be maintainable by many people in Apache Commons.




-- 
Stian Soiland-Reyes
University of Manchester
http://www.esciencelab.org.uk/
http://orcid.org/0000-0001-9842-9718


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: RDF commons testing

Posted by Peter Ansell <an...@gmail.com>.
Hi Claude,

Abstract test classes are working well for Commons RDF so far. Others
may benefit from your solution, so feel free to suggest the approach
to others who may be interested in exploring it.

Cheers,

Peter

On 30 January 2017 at 03:11, Claude Warren <cl...@xenei.com> wrote:
> Peter,
>
> I have written a more detailed discussion of why abstract tests for
> interfaces pose problems (
> https://www.linkedin.com/pulse/contract-testing-why-abstract-tests-enough-claude-warren-jr).
> I stand by my earlier assertions and offers.
>
> Claude
>
> On Sun, Jan 29, 2017 at 5:11 AM, Peter Ansell <an...@gmail.com>
> wrote:
>
>> On 28 January 2017 at 21:08, Claude Warren <cl...@xenei.com> wrote:
>> > I see that RDF Commons is listed as a set of interfaces to be implemented
>> > on top of various RDF implementations.  I also see that there are
>> abstract
>> > tests for the interfaces.
>> >
>> > I would like to suggest that RDF commons look at using Junit Contract
>> tests
>> > (https://github.com/Claudenw/junit-contracts) which will ensure that
>> tests
>> > for all the implemented interfaces are run against the implementing
>> classes.
>> >
>> > The strategy for junit-contracts is to create interface tests into which
>> an
>> > instance of the object being tested is injected.  Implementation test
>> > suites are created by declaring the class under test and a mechanism to
>> > create the instance of the class.  The contract-test junit runner then
>> > locates all tests for all interfaces that are implemented by the class
>> > under test and runs them (A dynamic suite if you will).
>> >
>> > As interface tests are developed they are automatically picked up by the
>> > suites.  As interfaces are implemented by classes the suites
>> automatically
>> > pick up existing tests.  The maven plugins (and command line tools) will
>> > report on the interfaces that don't have tests as well as classes that
>> > don't have tests suites defined.
>> >
>> > Besides the convenience of the system finding the tests to run this
>> > strategy has several other advantages:
>> >
>> > 1.  It allows classes that implement multiple interfaces to have one test
>> > that tests them all.  Developers no longer have to track down abstract
>> test
>> > classes across multiple projects and create concrete implementations.
>> >
>> > 2.  It allows developers to quickly determine if their implementation
>> > matches the full contract for the interface.
>> >
>> > 3.  It means that refactoring of parent interfaces / classes do not force
>> > additional coding for the testing of derived classes.
>> >
>> > If you are interested I would be glad to help convert existing tests to
>> > contract tests.
>>
>> Hi Claude,
>>
>> The existing abstract tests already fulfill the purposes you describe
>> using the basic JUnit features.
>>
>> Cheers,
>>
>> Peter
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
>
>
> --
> I like: Like Like - The likeliest place on the web
> <http://like-like.xenei.com>
> LinkedIn: http://www.linkedin.com/in/claudewarren

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: RDF commons testing

Posted by Claude Warren <cl...@xenei.com>.
Peter,

I have written a more detailed discussion of why abstract tests for
interfaces pose problems (
https://www.linkedin.com/pulse/contract-testing-why-abstract-tests-enough-claude-warren-jr).
I stand by my earlier assertions and offers.

Claude

On Sun, Jan 29, 2017 at 5:11 AM, Peter Ansell <an...@gmail.com>
wrote:

> On 28 January 2017 at 21:08, Claude Warren <cl...@xenei.com> wrote:
> > I see that RDF Commons is listed as a set of interfaces to be implemented
> > on top of various RDF implementations.  I also see that there are
> abstract
> > tests for the interfaces.
> >
> > I would like to suggest that RDF commons look at using Junit Contract
> tests
> > (https://github.com/Claudenw/junit-contracts) which will ensure that
> tests
> > for all the implemented interfaces are run against the implementing
> classes.
> >
> > The strategy for junit-contracts is to create interface tests into which
> an
> > instance of the object being tested is injected.  Implementation test
> > suites are created by declaring the class under test and a mechanism to
> > create the instance of the class.  The contract-test junit runner then
> > locates all tests for all interfaces that are implemented by the class
> > under test and runs them (A dynamic suite if you will).
> >
> > As interface tests are developed they are automatically picked up by the
> > suites.  As interfaces are implemented by classes the suites
> automatically
> > pick up existing tests.  The maven plugins (and command line tools) will
> > report on the interfaces that don't have tests as well as classes that
> > don't have tests suites defined.
> >
> > Besides the convenience of the system finding the tests to run this
> > strategy has several other advantages:
> >
> > 1.  It allows classes that implement multiple interfaces to have one test
> > that tests them all.  Developers no longer have to track down abstract
> test
> > classes across multiple projects and create concrete implementations.
> >
> > 2.  It allows developers to quickly determine if their implementation
> > matches the full contract for the interface.
> >
> > 3.  It means that refactoring of parent interfaces / classes do not force
> > additional coding for the testing of derived classes.
> >
> > If you are interested I would be glad to help convert existing tests to
> > contract tests.
>
> Hi Claude,
>
> The existing abstract tests already fulfill the purposes you describe
> using the basic JUnit features.
>
> Cheers,
>
> Peter
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>


-- 
I like: Like Like - The likeliest place on the web
<http://like-like.xenei.com>
LinkedIn: http://www.linkedin.com/in/claudewarren

Re: RDF commons testing

Posted by Peter Ansell <an...@gmail.com>.
On 28 January 2017 at 21:08, Claude Warren <cl...@xenei.com> wrote:
> I see that RDF Commons is listed as a set of interfaces to be implemented
> on top of various RDF implementations.  I also see that there are abstract
> tests for the interfaces.
>
> I would like to suggest that RDF commons look at using Junit Contract tests
> (https://github.com/Claudenw/junit-contracts) which will ensure that tests
> for all the implemented interfaces are run against the implementing classes.
>
> The strategy for junit-contracts is to create interface tests into which an
> instance of the object being tested is injected.  Implementation test
> suites are created by declaring the class under test and a mechanism to
> create the instance of the class.  The contract-test junit runner then
> locates all tests for all interfaces that are implemented by the class
> under test and runs them (A dynamic suite if you will).
>
> As interface tests are developed they are automatically picked up by the
> suites.  As interfaces are implemented by classes the suites automatically
> pick up existing tests.  The maven plugins (and command line tools) will
> report on the interfaces that don't have tests as well as classes that
> don't have tests suites defined.
>
> Besides the convenience of the system finding the tests to run this
> strategy has several other advantages:
>
> 1.  It allows classes that implement multiple interfaces to have one test
> that tests them all.  Developers no longer have to track down abstract test
> classes across multiple projects and create concrete implementations.
>
> 2.  It allows developers to quickly determine if their implementation
> matches the full contract for the interface.
>
> 3.  It means that refactoring of parent interfaces / classes do not force
> additional coding for the testing of derived classes.
>
> If you are interested I would be glad to help convert existing tests to
> contract tests.

Hi Claude,

The existing abstract tests already fulfill the purposes you describe
using the basic JUnit features.

Cheers,

Peter

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org