Redesigning JUnit Asserts

After reading about Behaviour Driven Development, using jMock for a while, and since I am very fond of Ruby‘s core class APIs, I am sure the assertations of JUnit need a major overhaul.

This are the goals I have for the redesign:

  • Make the code expressive and as readable as possbile. This means the code should look like plain english.
  • Usability is more important than flexibility.
  • Allow for much more poweful checks.

Usability is very important. The good thing is that it is easy to analyze how JUnit is used (download some test driven developed open source projects, grep for assertTrue, and there you have all the cases where JUnit’s asserts were not good enough :-))

I am playing around with a few ideas, and this is the API I am currently after:

Assertions Example Usage

Starting point is always ensure(). You put in the actual value, then execute some operations that modify the following constraint check, then the last command is the constraint check. The last command is always the constraint check, so you can only do one check per line of code. That’s not as flexible as jMock, but it is simpler and more readable and good enough.

Technically all this is very doable. Probably quite a bit of work, and most likely requires a code generator since lots of code is almost the same but not reusable (e.g. arrays for primitive data types), but that’s not a problem. I have done a few simple feasibility studies and I don’t see a big problem with this interface.

Please tell me what you think about this!

Updates

From time to time I will update this page with progress reports, until I have something that is stable enough to give away.

2006-08-05
I have started developing this. So far I am very happy with it, its a fun project to implement ๐Ÿ™‚ I will probably create a project on sourceforge and opensource it, but I am not sure about the licence.

8 Comments on "Redesigning JUnit Asserts"

Notify of
avatar
Jens Dornieden
Guest

Very interesting idea! That would be a nice way to provide many of the standard checks everyone needs.

What I don’t like is that you kind of “abuse” the methods to make the code look more like plain english:
– the method “ensure” wouldn’t ensure anything but return some wrapper (I guess).
– a method “contains()” without a parameter looks very weird because one would expect the object to test here.

Why don’t you use something like:
object(a).contains(neither(3,4));

In my opinion that wouldn’t be much less readable but would look more like Java.

Another thing that comes to mind: how would you handle user defined objects?

Jens

martinus
Guest
Hi, thanks for your comment! You are right that this is not really the typical java style. – object() is not the right choice either, because I am not objecting anything ๐Ÿ™‚ – The syntax with contains(neither(3,4)) is a bit cleaner, but then I have the problem that I need lots of other static methods. Currently only ensure() needs to be a static method. I think it should not be difficult to write ensure() methods for user defined objects. Just write the static method ensure(), and then you can reuse the functionality of the other checker implementations. e.g. if you… Read more ยป
Jens
Guest
Yeah, you’re right! object() wasn’t that good idea!:-) Why do you need static methods at all? The problem with static methods is that you can’t overwrite them. I thought you would implement a new TestCase class with a method “ensure()”? I agree with you that you would need too many methods for contains(neither(3,4)). Maybe containsNeither(3,4)? I’ve still got the feeling that user defined objects are a problem. Of course it would be easy to write my own ensure() but I have much more to do than I have when using JUnit. E.g. if I have got a class “Candle” and… Read more ยป
martinus
Guest

I would like to have static methods because I like the way junit4 uses the import static:
http://www-128.ibm.com/developerworks/java/library/j-junit4.html
this way it would be very easy to use the ensure() in your existing unit tests, just import the methods and you can use them. No need to extend TestCase.

I was also thinking about the containsNeither syntax, but then you quickly get a hell of a lot of different methods, and it is difficult to reuse code.

instead of
ensure(candle).isBurning()
you can use ensure(candle.isBurning()).isTrue()

With the basic checks you can also write
ensure(candle.length()).between(30,34)
so you do not really always need to write custom test classes.

Roy van Rijn
Guest

If you decide to use Java 5 you should use varargs for the either() / neither(). In case you don’t have experience yet with varargs:

Instead of overloading either() like this:

boolean either(Object e1);
boolean either(Object e1, Object e2);

With varargs:

boolean either(Object… e1);
(this is like passing a array into the function)

Roy van Rijn
Guest

Oops, forgot a part of my message.
If you put it on sf.net I’d probably use it! I’m a big fan of jUnit and I really like the way you are making it more readable. This could also be usefull in the IT company I work for, maybe some testers could write their own testcases with this.

So please open-source it… and don’t forget to notify me when you do! Btw. the Belgian branch of our company is working on a jUnit project too:
http://unitils.sourceforge.net/

Maybe the two could then be integrated if you(/and them) want.

martinus
Guest

Hi Roy, the ensure4j library is shaping up quite nicely. I am using Java 5 and am already using varargs whenever appropriate ๐Ÿ™‚

The ensure() syntax has already proven to be very useful, e.g. I have added statistical tests that make it possible to e.g. verify the quality of optimizers.

I would love to make this open source, but I have developed it at work while working on another project so I am not sure if I can convince my boss to do this.

trackback

[…] As part of another project I am developing ensure4j. The syntax (see the examples here) is working quite nicely, ensure4j is already very useful for internal use. […]

wpDiscuz