Git Product home page Git Product logo

Comments (12)

Claudenw avatar Claudenw commented on June 15, 2024

What test runner did you use to run the tests?

I build with Eclipse and I think that its test runners do not handle tests with no annotated test cases the same way as others. At least that I what I think the issue is. I will delve deeper this evening.

from junit-contracts.

jbrains avatar jbrains commented on June 15, 2024

On Wed, Oct 23, 2013 at 3:21 AM, Claude Warren [email protected]:

What test runner did you use to run the tests?

I ran mvn package from the command line. Mac OS. Java HotSpot VM
1.8.0-ea-b94.

I build with Eclipse and I think that its test runners do not handle tests
with no annotated test cases the same way as others. At least that I what I
think the issue is. I will delve deeper this evening.

If the test class inherits tests, then it should work. If the test class
intentionally has no tests because others should inherit from it, then mark
it abstract so that the test runner doesn't try to run it. I've always

marked the contract test classes abstract for exactly this reason.

J. B. (Joe) Rainsberger :: http://www.myagiletutor.com ::
http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Free Your Mind to Do Great Work :: http://www.freeyourmind-dogreatwork.com

from junit-contracts.

Claudenw avatar Claudenw commented on June 15, 2024

This is Junit 4.x so no inheriting from tests.

I can't mark it abstract since then I can't instantiate it inside the
ConstractSuite runner. I did have a version 0.0.1 that created concrete
classes but that was a problem because it left lots of code laying around
in the /tmp directory and it would not be cleaned up on continuous
integration systems.

I ran it on Mac OS this afternoon both in eclipse and from the mvn command
line using "mvn test" . That also works from my Ubuntu box at home.

On Wed, Oct 23, 2013 at 6:09 PM, J. B. Rainsberger <[email protected]

wrote:

On Wed, Oct 23, 2013 at 3:21 AM, Claude Warren <[email protected]

wrote:

What test runner did you use to run the tests?

I ran mvn package from the command line. Mac OS. Java HotSpot VM
1.8.0-ea-b94.

I build with Eclipse and I think that its test runners do not handle
tests
with no annotated test cases the same way as others. At least that I
what I
think the issue is. I will delve deeper this evening.

If the test class inherits tests, then it should work. If the test class
intentionally has no tests because others should inherit from it, then mark
it abstract so that the test runner doesn't try to run it. I've always

marked the contract test classes abstract for exactly this reason.

J. B. (Joe) Rainsberger :: http://www.myagiletutor.com ::
http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Free Your Mind to Do Great Work :: http://www.freeyourmind-dogreatwork.com


Reply to this email directly or view it on GitHubhttps://github.com//issues/3#issuecomment-26923669
.

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

from junit-contracts.

Claudenw avatar Claudenw commented on June 15, 2024

I just duplicated the error here at home. I'll be exploring it now.

On Wed, Oct 23, 2013 at 6:31 PM, Claude Warren [email protected] wrote:

This is Junit 4.x so no inheriting from tests.

I can't mark it abstract since then I can't instantiate it inside the
ConstractSuite runner. I did have a version 0.0.1 that created concrete
classes but that was a problem because it left lots of code laying around
in the /tmp directory and it would not be cleaned up on continuous
integration systems.

I ran it on Mac OS this afternoon both in eclipse and from the mvn command
line using "mvn test" . That also works from my Ubuntu box at home.

On Wed, Oct 23, 2013 at 6:09 PM, J. B. Rainsberger <
[email protected]> wrote:

On Wed, Oct 23, 2013 at 3:21 AM, Claude Warren <[email protected]

wrote:

What test runner did you use to run the tests?

I ran mvn package from the command line. Mac OS. Java HotSpot VM
1.8.0-ea-b94.

I build with Eclipse and I think that its test runners do not handle
tests
with no annotated test cases the same way as others. At least that I
what I
think the issue is. I will delve deeper this evening.

If the test class inherits tests, then it should work. If the test class
intentionally has no tests because others should inherit from it, then
mark
it abstract so that the test runner doesn't try to run it. I've always

marked the contract test classes abstract for exactly this reason.

J. B. (Joe) Rainsberger :: http://www.myagiletutor.com ::
http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Free Your Mind to Do Great Work ::
http://www.freeyourmind-dogreatwork.com


Reply to this email directly or view it on GitHubhttps://github.com//issues/3#issuecomment-26923669
.

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

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

from junit-contracts.

jbrains avatar jbrains commented on June 15, 2024

I inherit even in JUnit 4, because the tests for ArrayList are the contract tests for List plus possibly some other implementation detail tests. If ever there were a textbook usage of inheriting implementation, this is it. :)

from junit-contracts.

Claudenw avatar Claudenw commented on June 15, 2024

The tests for ArrayList are tests for ArrayList. The ContractSuite finds all the interfaces that ArrayList implements, and then finds the Contract tests for those interfaces. It then dynamically adds the those tests to the ArrayList suite and executes them.

ArrayList should not include direct tests for the List interface because while we don't expect the List interface to change our understanding of how to test it may. That is we may find errors that others have made in the List implementation and add tests for those. ArrayList should not have to know about those changes unless ArrayList too has misimplemented the List interface.

There should be something like this

Interface        Contract Test annotation
List                @Contract(List.class) 
Serializable     @Contract(Serializable.class)
Iterable           @Contract(Iterable.class)
Collection        @Contract(Collection.class)
RandomAccess @Contract(RandomAccess.class)

Classes          Contract Suite annotation in addition to @RunWith(Contract.Suite)
ArrayList         @ContractImpl(ArrayList.class)
AttributeList     @ContractImpl(AttributeList.class)
RoleList           @ContractImpl(RoleList.class)

note that AttributeList and RoleList are derived from ArrayList.

So running the ArrayList test will run all the tests listed in ArrayList as well as all the tests listed for List, Serializable, Iterable, Collection, and RandomAccess.

Assuming the AttributeList test is derived from the ArrayList test all of the above plus the AttributeList tests will be run. The same goes for RoleList.

Anyway. If found the bug and a fix will be uploaded shortly.

from junit-contracts.

Claudenw avatar Claudenw commented on June 15, 2024

jbrains, please let me know if this fixes the issue for you.

from junit-contracts.

jbrains avatar jbrains commented on June 15, 2024

On Wed, Oct 23, 2013 at 3:06 PM, Claude Warren [email protected]:

The tests for ArrayList are tests for ArrayList. The ContractSuite finds
all the interfaces that ArrayList implements, and then finds the Contract
tests for those interfaces. It then dynamically adds the those tests to the
ArrayList suite and executes them.

This makes sense. So ContractSuite knows that ArrayList implements List,
looks for tests marked with "I'm part of the contract of List" and runs
them for instances of ArrayList. Instead of inheriting the contract, the
ArrayList tests treat the tests for List as a template and merges them with
a producer for instances of ArrayList. Neat. I never thought of doing it
that way.

ArrayList should not include direct tests for the List interface because
while we don't expect the List interface to change our understanding of how
to test it may.

I disagree with "should not" here. The LSP requires that all
implementations of List pass the same set of tests, because that's how we
define runtime substitutability.

That is we may find errors that others have made in the List
implementation and add tests for those. ArrayList should not have to know
about those changes unless ArrayList too has misimplemented the List
interface.

By adding the new contract tests to ListContract, ArrayList's test inherit
them automatically without having to know about them. If it's part of the
abstract behavior of all List implementations and it's important enough to
check in one implementation of List, then it's important enough to check in
all implementations of List. To do otherwise risks breaking LSP in
particular and polymorphism in general.

They seem to me to be two ways to approach the same problem. Annotations
offer the advantage that all the ArrayList tests could be in one place
(including the contracts of List, Collection, RandomAccess, Iterable,
Serializable), whereas inheriting (and having multiple test classes for
ArrayList's tests) makes the relationship more obvious. I like your
template-ish approach, and with this example, I understand it better.
Thanks.

Anyway. If found the bug and a fix will be uploaded shortly.

Marvelous.

J. B. (Joe) Rainsberger :: http://www.myagiletutor.com ::
http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Free Your Mind to Do Great Work :: http://www.freeyourmind-dogreatwork.com

from junit-contracts.

Claudenw avatar Claudenw commented on June 15, 2024

The ArrayList class has the following inheritance:

AbstractCollection -> AbstractList -> ArrayList

AbstractList is actually the first class that implements List in that
hierarchy.

But as I noted in another email, list is implemented by a bunch of classes
and most, if not all of those classes, have other classes as parents. Thus
the List tests have to be duplicated in a number of places. It is this
duplication that I am trying to get away from.

On Wed, Oct 23, 2013 at 7:37 PM, J. B. Rainsberger <[email protected]

wrote:

On Wed, Oct 23, 2013 at 3:06 PM, Claude Warren <[email protected]

wrote:

The tests for ArrayList are tests for ArrayList. The ContractSuite finds
all the interfaces that ArrayList implements, and then finds the Contract
tests for those interfaces. It then dynamically adds the those tests to
the
ArrayList suite and executes them.

This makes sense. So ContractSuite knows that ArrayList implements List,
looks for tests marked with "I'm part of the contract of List" and runs
them for instances of ArrayList. Instead of inheriting the contract, the
ArrayList tests treat the tests for List as a template and merges them with
a producer for instances of ArrayList. Neat. I never thought of doing it
that way.

ArrayList should not include direct tests for the List interface because
while we don't expect the List interface to change our understanding of
how
to test it may.

I disagree with "should not" here. The LSP requires that all
implementations of List pass the same set of tests, because that's how we
define runtime substitutability.

That is we may find errors that others have made in the List
implementation and add tests for those. ArrayList should not have to know
about those changes unless ArrayList too has misimplemented the List
interface.

By adding the new contract tests to ListContract, ArrayList's test inherit
them automatically without having to know about them. If it's part of the
abstract behavior of all List implementations and it's important enough to
check in one implementation of List, then it's important enough to check in
all implementations of List. To do otherwise risks breaking LSP in
particular and polymorphism in general.

They seem to me to be two ways to approach the same problem. Annotations
offer the advantage that all the ArrayList tests could be in one place
(including the contracts of List, Collection, RandomAccess, Iterable,
Serializable), whereas inheriting (and having multiple test classes for
ArrayList's tests) makes the relationship more obvious. I like your
template-ish approach, and with this example, I understand it better.
Thanks.

Anyway. If found the bug and a fix will be uploaded shortly.

Marvelous.

J. B. (Joe) Rainsberger :: http://www.myagiletutor.com ::
http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Free Your Mind to Do Great Work :: http://www.freeyourmind-dogreatwork.com

Reply to this email directly or view it on GitHubhttps://github.com//issues/3#issuecomment-26932471
.

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

from junit-contracts.

jbrains avatar jbrains commented on June 15, 2024

On Wed, Oct 23, 2013 at 3:58 PM, Claude Warren [email protected]:

The ArrayList class has the following inheritance:

AbstractCollection -> AbstractList -> ArrayList

AbstractList is actually the first class that implements List in that
hierarchy.

But as I noted in another email, list is implemented by a bunch of classes
and most, if not all of those classes, have other classes as parents. Thus
the List tests have to be duplicated in a number of places. It is this
duplication that I am trying to get away from.

I don't duplicate them. I put them in abstract class ListContract with
abstract methods (like createEmptyList()) that correspond to your Producer
interface. Every implementation of List can inherit the ListContract to get
those tests.

I like the template-based approach, though. I look forward to trying it out.

J. B. (Joe) Rainsberger :: http://www.myagiletutor.com ::
http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Free Your Mind to Do Great Work :: http://www.freeyourmind-dogreatwork.com

from junit-contracts.

Claudenw avatar Claudenw commented on June 15, 2024

The problem is you can't extend ListTest class if the class under test also
extends another class. As an example:

org.mozilla.javascript.NativeArray extends
org.mozilla.javascript.IdScriptableObject which extends
org.mozilla.javascript.ScriptableObject. NativeArray implements List so
its test can not simply extend the list test since it has to extend
the IdScriptableObject tests.

Returning to the ArrayList example. ArrayList also implements RandomAccess
so if you want to include both the RandomAccess and ArrayList tests you
have to duplicate code of one or the other.

On Wed, Oct 23, 2013 at 8:28 PM, J. B. Rainsberger <[email protected]

wrote:

On Wed, Oct 23, 2013 at 3:58 PM, Claude Warren <[email protected]

wrote:

The ArrayList class has the following inheritance:

AbstractCollection -> AbstractList -> ArrayList

AbstractList is actually the first class that implements List in that
hierarchy.

But as I noted in another email, list is implemented by a bunch of
classes
and most, if not all of those classes, have other classes as parents.
Thus
the List tests have to be duplicated in a number of places. It is this
duplication that I am trying to get away from.

I don't duplicate them. I put them in abstract class ListContract with
abstract methods (like createEmptyList()) that correspond to your Producer
interface. Every implementation of List can inherit the ListContract to get
those tests.

I like the template-based approach, though. I look forward to trying it
out.

J. B. (Joe) Rainsberger :: http://www.myagiletutor.com ::
http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Free Your Mind to Do Great Work :: http://www.freeyourmind-dogreatwork.com

Reply to this email directly or view it on GitHubhttps://github.com//issues/3#issuecomment-26937906
.

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

from junit-contracts.

jbrains avatar jbrains commented on June 15, 2024

On Wed, Oct 23, 2013 at 6:00 PM, Claude Warren [email protected]:

org.mozilla.javascript.NativeArray extends
org.mozilla.javascript.IdScriptableObject which extends
org.mozilla.javascript.ScriptableObject. NativeArray implements List so
its test can not simply extend the list test since it has to extend
the IdScriptableObject tests.

I notice that you keep assuming that all the tests for a class need to be
in the same test class. They don't. NativeArray does at least two things:
it conforms to the IdScriptableObject contract and the List contract. I'd
have one test class for NativeArray that checks the IdScriptableObject
contract, one test class that checks the ListContract and another for
NativeArray's implementation details. At least.

Returning to the ArrayList example. ArrayList also implements RandomAccess

so if you want to include both the RandomAccess and ArrayList tests you
have to duplicate code of one or the other.

In this particular case, RandomAccess is a marker interface, so there's no
explicit contract. At most, one might write an execution speed test,
sampling get(i) for various values of i to show that they're roughly
equally fast.

I don't see the duplicate code between the contracts for two independent
interfaces, meaning that neither extends the other, except as a design

mistake. Can you think of a counterexample?

J. B. (Joe) Rainsberger :: http://www.myagiletutor.com ::
http://www.jbrains.ca ::
http://blog.thecodewhisperer.com
Free Your Mind to Do Great Work :: http://www.freeyourmind-dogreatwork.com

from junit-contracts.

Related Issues (11)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.