OR assertions

5 views
Skip to first unread message

oae

unread,
Nov 18, 2010, 9:15:56 AM11/18/10
to easytesting
Dear festlers,

i'm using fest-assertions since a couple of weeks and i like the
approach very much. Together with mockito unit tests can be realy
clean, simple and powerful!

However, what i'm missing from time to time is the ability for an "OR"-
binding of assertions, instead of the AND one. Something like
assertThat(variable).isEqualTo(a).or().isEqualTo(b);

Is there any support or workaround for things like that ?

best regards
Johannes

Alex Ruiz

unread,
Nov 18, 2010, 10:04:28 AM11/18/10
to easyt...@googlegroups.com
Hi Johannes,

Currently we don't support "or" out-of-the-box. I still don't know how we can achieve that in FEST. One approach could be like the one you showed:

assertThat(variable).isEqualTo(a).or().isEqualTo(b);

which is pretty understandable, but hard to implement (we'll need to keep state after "or" and then batch all the following assertions.)

or, we could do that with Conditions (a la Hamcrest):

assertThat(variable).is(or(isEqualTo(a), isEqualTo(b));

The bad news is that our current code base (1.x) doesn't make it easy to reuse FEST code for writing Conditions. The good news is that extensibility and custom Conditions will be theme for the design of 2.x (some of us have already started playing with different designs.)

Please file a JIRA ticket. This way we won't forget to add a "or" glue for conditions.

Many thanks,
-Alex


--
You received this message because you are subscribed to the Google Groups "easytesting" group.
To post to this group, send email to easyt...@googlegroups.com.
To unsubscribe from this group, send email to easytesting...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/easytesting?hl=en.


szczepiq

unread,
Nov 18, 2010, 10:38:37 AM11/18/10
to easyt...@googlegroups.com
Hey Johannes,

>assertThat(variable).isEqualTo(a).or().isEqualTo(b);

May I know why your test does not know if it is 'a' or 'b'? Are you testing a random generator or you don't know your code? :-)

Thanks for mentioning Mockito - you made my day :)

Cheers,
Szczepan

oae

unread,
Nov 18, 2010, 11:35:02 AM11/18/10
to easytesting
On Nov 18, 4:38 pm, szczepiq <szcze...@gmail.com> wrote:
> Hey Johannes,
>
> >assertThat(variable).isEqualTo(a).or().isEqualTo(b);
>
> May I know why your test does not know if it is 'a' or 'b'?

No! ;)

i havn't a good example right now and my brains feels a little tired
but i know i stumbled over this from time to time...

cheers
Johannes

oae

unread,
Nov 18, 2010, 11:48:49 AM11/18/10
to easytesting
On Nov 18, 4:04 pm, Alex Ruiz <alex.ruiz...@gmail.com> wrote:
> The bad news is that our current code base (1.x) doesn't make it easy to
> reuse FEST code for writing Conditions. The good news is that extensibility
> and custom Conditions will be theme for the design of 2.x (some of us have
> already started playing with different designs.)
>
> Please file a JIRA ticket. This way we won't forget to add a "or" glue for
> conditions.

Done: http://jira.codehaus.org/browse/FEST-406
Sounds good so far..
I added a comment to jira ticket about the different approaches...

Thanks
Johannes

szczepiq

unread,
Nov 18, 2010, 12:05:32 PM11/18/10
to easyt...@googlegroups.com
It feels that if the test does not really know what is the outcome of the tested behaviour then... there's something wrong with a test or with a code (or both ;). IMHO, there are no reasonable use cases for such feature. But that's just my feedback =) If you implement specific or() I will simply not use it and hope my devs don't use them :) Better Conditions in 2.0 might naturally satisfy this feature request.

Cheers
Szczepan

Johannes

Adam

unread,
Nov 18, 2010, 12:16:07 PM11/18/10
to easyt...@googlegroups.com, jzil...@googlemail.com
oae wrote:

> assertThat(variable).isEqualTo(a).or().isEqualTo(b);
>
> Is there any support or workaround for things like that ?

I didn't test it, but the obvious workaround would be:

try {
assertThat(variable).isEqualTo(a);
catch (AssertionError e) {
assertThat(variable).isEqualTo(b);
}

Which is terribly ugly of course. I haven't hacked on fest so I wouldn't
be surprised to be corrected (more so if not), but couldn't that be
"sugared" (with a big patch) into the following syntax?

assertThat(variable).begin().isEqualTo(a).or().isEqualTo(b).end();

Almost Java code follows.

--Adam


public class ObjectAssert … {

public OrableObjectAssert begin() {
return new OrableObjectAssert(this);
}
}

public class OrableObjectAssert implements ObjectAssert {

protected OrableObjectAssert(ObjectAssert decorated) {
this.originalDecorated = decorated;
this.currentDecorated = decorated;
this.assertErros = new LinkedList<AssertionError>();
this.isTrue = true;
}

public OrableObjectAssert isEqualTo(Object expected) {
try {
if (isTrue)
currentDecorated = currentDecorated.isEqualTo(expected);
} catch (AssertionError e) {
assertErros.append(e);
isTrue = false;
}
return this;
}

public OrableObjectAssert or() {
if (isTrue) {
return new NeverRaisingObjectAssert(currentDecorated);
} else {
currentDecorated = originalDecorated;
isTrue = true;
return this;
}
}

public ObjectAssert end() {
if (assertErros.length != 0)
raise joinErrors(assertErros);
return currentDecorated;
}
}

signature.asc

Dale Emery

unread,
Nov 18, 2010, 1:38:12 PM11/18/10
to easyt...@googlegroups.com
Hi Alex,

Currently we don't support "or" out-of-the-box. I still don't know how we can achieve that in FEST. One approach could be like the one you showed:

assertThat(variable).isEqualTo(a).or().isEqualTo(b);

which is pretty understandable, but hard to implement (we'll need to keep state after "or" and then batch all the following assertions.)

Consider a syntax like this:

assertThat(variable).either().isEqualTo(a).or().isEqualTo(b);

The either() method could return an object that collects the state from the later methods in the chain.

Dale

-- 
Dale Emery
Consultant to software teams and leaders
Web: http://dhemery.com

Bartosz Bańkowski

unread,
Nov 18, 2010, 1:43:13 PM11/18/10
to easyt...@googlegroups.com
Hi All,

It seems to me that you are trying to come up with a generic solution
for a case that doesn't have a valid real life example. Conditional
logic in tests is a smell. If I had a need to write an assertion like
that, I'd have rather create my own:

assertThat(something).isEqualToAnyOf(a, b)

Best regards,
Bartosz

Jean-Francois Poilpret

unread,
Nov 18, 2010, 3:37:14 PM11/18/10
to easyt...@googlegroups.com
On 18-11-2010 19:43, Bartosz Bańkowski wrote:
> Hi All,
>
> It seems to me that you are trying to come up with a generic solution
> for a case that doesn't have a valid real life example. Conditional
> logic in tests is a smell. If I had a need to write an assertion like
> that, I'd have rather create my own:
>
> assertThat(something).isEqualToAnyOf(a, b)
I second Bartosz' idea, I found using a fluent API for such assertions is:
- a smell for the test case or the tested code
- complex to read (for the test case)
- complex to implement
- is not really useful for most test cases

If it needs be, then definitely you'd better use a isEqualToOneOf(T...)
method, which:
- is easy to implement
- is easily understood when reading test cases
- is easy to use when writing a TC
For the implementation, one may want to guarantee that there is at least
one argument:
isEqualToOneOf(T a, T... others)
that makes the implementation just a little bit more complex but ensures
no one can write an assertion like:
assertThat(something).isEqualToOneOf();
which is obviously meaningless.

Just my 2 cents

Jean-Francois

Joel Costigliola

unread,
Nov 18, 2010, 4:02:15 PM11/18/10
to easytesting
Hi Guys,

In the next Fest release, we will support isIn assertion that should
answer the request (correct me if I'm wrong)

instead of :
assertThat(variable).isEqualTo(a).or().isEqualTo(b);

just write :
assertThat(variable).isIn(a, b);

Note that isIn supports also collection parameters so that one can
write
Collection myCollection = ... ;// init a collection with a and b
assertThat(variable).isIn(myCollection);

Oh, by the way, you will also have an isNotIn assertion ;-)

See Jira http://jira.codehaus.org/browse/FEST-400

Regards,

Joel


On Nov 18, 9:37 pm, Jean-Francois Poilpret <jfpoilp...@gmail.com>
wrote:

Joel Costigliola

unread,
Nov 19, 2010, 3:58:31 AM11/19/10
to easytesting
To be precise, isIn assertion only offers 'or' semantic with
'isEqualTo' condition, so you can't do something like :
assertThat(size).isEqualTo(5).or().isLessThan(2)

Joel

On Nov 18, 10:02 pm, Joel Costigliola <joel.costigli...@gmail.com>
wrote:
> Hi Guys,
>
> In the next Fest release, we will support isIn assertion that should
> answer the request (correct me if I'm wrong)
>
> instead of :
> assertThat(variable).isEqualTo(a).or().isEqualTo(b);
>
> just write :
> assertThat(variable).isIn(a, b);
>
> Note that isIn supports also collection parameters so that one can
> write
> Collection myCollection  = ... ;// init a collection with a and b
> assertThat(variable).isIn(myCollection);
>
> Oh, by the way, you will also have an isNotIn assertion ;-)
>
> See Jirahttp://jira.codehaus.org/browse/FEST-400

oae

unread,
Nov 19, 2010, 4:33:46 AM11/19/10
to easytesting
Hi guys,

even if it smells... you can't do everytime everything perfect. And if
adding an or-clause takes me 2 minutes instead of rewriting 10 test
and make sure they work in 3 hours, i would consider to do it,
depending on the circumstances.

Some examples i picked from the current test-base i'm working with:
- asserting a Long where it doesn't matter to me if its null or 0
assertThat(failMessage, longValue, anyOf(nullValue(), equalTo(0L)));
- a abstract jdbc test which is implemented by several dialacts
assertThat(resultSet.getMetaData().getColumnType(3),
anyOf(is(Types.DOUBLE), is(Types.REAL), is(Types.NUMERIC)));
- asserting the sorted keys of a sorted map: unsorted-
map={a=1,b=5,c=3,d=3}
assertThat(sortedMapKeys).containsOnly("a", "d",
"c","b").or().containsOnly("a", "c", "d","b");

No matter how persuading these examples are... i think an or-clause or
an anyOf-clause or similar things or such basic building blocks that
it would be a good addition to the framework!

cheers
Johannes

Mark Derricutt

unread,
Nov 25, 2010, 7:59:23 AM11/25/10
to easyt...@googlegroups.com
AFAIK this can't really be done without some compiler magic.

At leas the of batching the exceptions till the end - the problem is that there's no way to know which call is the last in the chain.

One could however do something like:

assertThat()
  .isEqualTo(a)
  .isEqualTo(b)
  .given(variable);

This reads well, and kinda follows the style of mockito's doReturn(x).when(mock).xxxxx.

assertThat() with no parameters returns an Assertion set in some lazy/non-throwy mode, which would store a list of actual Assertions to run in a static ThreadLocal somewhere.

assertThat(String.class)
  .contains("foo")
  .given("hello");

In this instance, assertThat(String.class) returs a StringAssertion - also set in the lazy mode.

Both of these would behave as normal, matching ALL assertion criteria, however - our any case could be cleanly done with:

assertThat(Assertion.ANY, String.class)
  .contains("foo")
  .contains("bar")
  .given("foobar");

Thoughts?
Mark


--
"Great artists are extremely selfish and arrogant things" — Steven Wilson, Porcupine Tree



On Fri, Nov 19, 2010 at 4:04 AM, Alex Ruiz <alex.r...@gmail.com> wrote:
assertThat(variable).isEqualTo(a).or().isEqualTo(b);

Johannes Schneider

unread,
Nov 26, 2010, 10:53:14 AM11/26/10
to easyt...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

One example: I used an external tool for image conversion (imagemagick).
Then I check the md5sum of the output. Now I'd like to support multiple
imagemagick versions that all return slightly different results.

Maybe not the best example... But that is one point where "or" might be
a fast fix.


Thanks,

Joahnnes Schneider

> easyt...@googlegroups.com <mailto:easyt...@googlegroups.com>.


> To unsubscribe from this group, send email to
> easytesting...@googlegroups.com

> <mailto:easytesting%2Bunsu...@googlegroups.com>.


> For more options, visit this group at
> http://groups.google.com/group/easytesting?hl=en.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "easytesting" group.
> To post to this group, send email to easyt...@googlegroups.com

> <mailto:easyt...@googlegroups.com>.


> To unsubscribe from this group, send email to
> easytesting...@googlegroups.com

> <mailto:easytesting%2Bunsu...@googlegroups.com>.


> For more options, visit this group at
> http://groups.google.com/group/easytesting?hl=en.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "easytesting" group.
> To post to this group, send email to easyt...@googlegroups.com.
> To unsubscribe from this group, send email to
> easytesting...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/easytesting?hl=en.

- --
Johannes Schneider - blog.cedarsoft.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iQEcBAEBAgAGBQJM79fmAAoJEAytD9R7Qv6dNQIH/1V89OOPqdlrW0/2Nn7yCYwI
+Wz2Xvvp4GdhUWeBcsXN6Fc2EKaxPi9U7/rrwuQTLCq2yAjOoJRE05H8xV3aZrJX
25USq1spAap+6L8qHVNo4LgMNJ+pOTX1Qqj66mrsFFPHedQNzDAjUQd6gCvJSeJK
9UG038slXcJ6WVHJbzd/94HS+42PryLElMbPKO66zT9PTMkwctDmZmJZFOcpOEUS
zjkVXbTuMoPxdEvhIuGjD8eYz2Bm1ikoZvFFHlPUp0YH5QddsfA98HtAu3cYAB8C
GiKOCQobhY18TXXK1itMUtdXCpYGwIi1XpaN6fGTq0V5iyXBKtxSznPuV98Ti0E=
=7P67
-----END PGP SIGNATURE-----

Ansgar Konermann

unread,
Nov 26, 2010, 12:00:17 PM11/26/10
to easyt...@googlegroups.com
Hi Johannes,

for the time being - that is without isIn(...) - you might try
something like:

assertThat(Arrays.asList(checksumOne, checksumTwo,
checksumThree)).contains(actualChecksum);

This of course reverts the actual vs. expected semantics of the
FEST-Assert API, so take care when the test actually fails and you try
to interpret the error message, but at least you have a working solution.

Best regards

Ansgar

Reply all
Reply to author
Forward
0 new messages