[phobos] Silent failure of std.container unittests

Jonathan M Davis jmdavisprog at gmail.com
Wed Jul 14 17:00:50 PDT 2010


On Wednesday, July 14, 2010 16:30:58 Walter Bright wrote:
> Jonathan M Davis wrote:
> > On the other hand, never halting on assertion failures makes for a lot
> > of cruft in your results.
> 
> I don't really understand why that's a problem, or causes extra work.
> 
> But I can see that having to divide up the tests into multiple unittest
> blocks adds extra work.
> _______________________________________________
> phobos mailing list
> phobos at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/phobos

Well, I find it perfectly normal having to divide up the unit tests since every 
unit testing framework that I've used divides up unit tests into functions where 
each function is a test that succeeds or fails. There may be many assertions in 
a particular function, but once one fails, that function ceases to run 
(generally because an exception was thrown which is then caught by the 
framework). So, it actually makes more sense to me to divide up tests into unit 
test blocks. True, if you're testing a set of small but unrelated stuff, it could 
make sense to put them all together in one test, but if you're testing blocks as 
a whole, then you have the choice of whether to break them up or not just like 
in another framework, you'd have the choice of whether you have a single 
function or multiple functions.

The cruft is a problem because it makes it harder to find the errors you actually 
care about. Unless you're checking a bunch of small, unrelated things, any 
assertion failure after the initial error is likely to be totally erroneous 
(since it was testing invalid state to begin with), so all of those errors just 
clutter the output, making it harder to find where one unittest block's tests end 
and where another begins (since it'll be the beginning of the next block where 
you'll start caring about errors again).

It's definitely better to run all tests in a block regardless of assertion 
failures than it is to stop running all of the unittests in a program or module 
because one assertion failed. However, I do think that it's better to not 
continue to run a particular unittest block after an assertion fails because 
then it's likely to be testing invalid state and report a bunch of errors which 
are irrelevant.

If you look at each unittest block as being a unit test testing a set of 
functionality rather than a particular assertion being the test, then it's just 
plain weird to continue to run the tests after the first assertion failed. The 
test already failed.

However, if you're viewing each assertion as a test with the idea that there may 
be many unrelated assertions together, then I can see why it might be desirable 
to have the block continue to be executed (since splitting them up would mean a 
lot of unittest blocks).

In any case, I do think that continuing to execute a unittest block after a 
failure is odd, and that it will result in a lot of unnecessary cruft, so I'd 
prefer that that didn't happen. However, it's definitely better to have the test 
continue than to stop them all after a single assertion failure. I suppose that 
the ideal solution would be to allow for both by having some way of indicating 
whether you wanted the test to continue after a particular assertion failure, 
but that would likely require multiple assertion types, which we don't have 
right now (at least not that the programmer can choose). Maybe if asserts threw 
normally (making it so that the first assertion failure in the unittest block 
resulted in that block ceasing execution, followed by the next unittest block 
being executed) but we had a library function of some kind which simply printed 
an error rather than throwing that would allow for the best of both worlds (like 
assert_nothrow() or something similar).

- Jonathan M Davis


More information about the phobos mailing list