I've seen a few variants on this idea. The "one assertion per test" maxim grew out of a reaction to people loading up tests with all sorts of unconnected assertions, so a test called testDatabase() might have tens of assertions (or worse) about all sorts of persistence stuff.

In that situation, the first assertion that failed would be the only one reported, which would hide other potential errors in the code. (The test suite wouldn't be any more "broken" in terms of the number of failing tests.)

When I'm coaching TDD or BDD now, I use the guideline of "one intent per method". You describe the intent with the method name, and verify it using expectations on mocks, post hoc assertions, or some combination of the two. If any of these fail, you then have a valid statement, that the code doesn't fulfil the intent of the behaviour method.

This is one of those incidental benefits that BDD gives you: having well-named behaviour methods gives you the granularity that one-assertion-per-test was striving for.

hth,
Dan


Michael Hunger wrote:
I'm just reading xUnit Test Patterns by Gerard Meszaros, there the one
assertion per method is softened by the fact that one could and should
create custom assertion methods (extract method) to assert complex state.

Please keep in mind the difference of asserting state or behaviour as
JBehaeve aims to. When asserting state the fail fast approach is often
useful as the assertions are placed in an order that shows their
dependency. Many assertions rely on the previous ones in order not to
generate Runtime Exceptions. So it is like the shortcut expression
evaluation of e.g. the and operator. You can rely on the fact that only
the expressions are evaluated that define the outcome of the whole
expression.

But if you _know_ that your assertions work in any order and with no
prerequisites/preconditions an allOf or checkAll operator would indeed be
very useful. Perhaps it could handle the different matchers so that
Runtime exceptions are also caught and reported as kind of the
aftereffects of a previous failure.

Thanks to Mauro for all the recent work.

Michael

On Fri, July 13, 2007 12:45 am, Shane Duan wrote:
I was reading this post
(http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html).
I agree that one assertion per test is nice but the overhead is big,
not to mention you need to figure out a way to show that three methods are
related to the same thing.

Then it hit me, maybe we can have both?


The problem with multiple assertion is that it stops at the first
failure.  But that was with JUnit, JBehave has its own framework!

We could change the and() behavior (or create another method like and)
that calls into ALL assertions and generate a comprehensive error message.

So


...
ensureThat(phoneNumber, and( areaCodeIs('738'), phoneNumberIs('233'),
extentionIs('333'))

...


now give:

failed * area code should be '738' but was null
* phone number should be '233' but was '738'
* extension should be '333' but was null


Thoughts?


--
Shane
http://www.shaneduan.com


---------------------------------------------------------------------
To unsubscribe from this list please visit:


http://xircles.codehaus.org/manage_email






Reply via email to