"Trip Volpe" <mraccid...@gmail.com> wrote in message 
news:hk4pql$1eh...@digitalmars.com...
>I recently began porting an existing C++ project of mine (a 
>compiler/interpreter for a dynamic language) to D. In the process I found 
>that the built-in unit testing support, while an awesome concept, was a 
>little bit sparse. In particular, assert() is fairly useless for unit 
>tests, since it throws on a failure and prevents all subsequent tests from 
>running.
>
> Unfortunately, it's the only facility that seems to give you access to the 
> current file and line number, very important bits of info for unit tests 
> in a any non-trivial project. I was contemplating just abandoning D and 
> sticking with C++ and Googletest, but after doing a bit of digging through 
> the source, I found setAssertHandler() in core.exception. Perfect! I could 
> use my own assert handler that just records the error and allows future 
> asserts to still be reached. So I wrote it up and gave it a try, but 
> pretty quickly started getting access violation errors.
>
> I did a bit of searching, and found a bug report on the issue:
>
> http://d.puremagic.com/issues/show_bug.cgi?id=3208
>
> In the comments it's indicated that this is intentional, that the compiler 
> expects the assertion handler to throw. So I guess I have a few questions:
>
> 1. Why is this the expected behavior? It seems to me that there are 
> relatively few useful things you can do with a custom assert handler 
> unless it is possible to refrain from throwing.
>
> 2. Is this going to be fixed any time soon? It seems fairly important to 
> me; it really kills the value of built-in unit tests to be forced to 
> choose between not having any line number information and being able to 
> recognize only one assert failure per test run(!!!).
>
> 3. Are there any current workarounds for the problem? I could just use my 
> own assertion function, but 1) I can't call it "assert" because that's a 
> reserved word, and 2) most importantly, it won't have any way of 
> indicating in its diagnostic output which source line the failure occurred 
> on. In C++, of course, I could use preprocessor macros to do that, but D 
> omits a preprocessor (for very good reasons). Unfortunately, this seems 
> like a case where D hasn't provided replacement functionality.
>
> But maybe there's a sneaky fix I haven't thought of? I also found 
> Runtime.moduleUnitTester() in core.runtime, which is very useful in 
> itself, but provides an _almost_ useful improvement: I can catch the 
> AssertErrors on a module-by-module basis, which would at least allow the 
> unit tests for all modules to be run regardless of a failure in one of 
> them. However, a single module could easily have dozens of tests in it, 
> each of which could contain many individual asserts. Stopping the test 
> early because one assert failed makes no sense.
>
> It would be _almost_ acceptable to at least be sure of running all the 
> tests in each module; is there any way to poke inside or otherwise 
> override ModuleInfo's unitTest() function?
>
>
> Thanks in advance for any advice or comments! D is a completely awesome 
> language, but I found this issue a bit strange.

The deferAssert module (possible name change and other API improvements 
pending) of my SemiTwist D Tools library ( 
http://www.dsource.org/projects/semitwist ) is designed to get around those 
problems. Here's a sample app with it's own output in the comments at the 
bottom:

http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/apps/tests/deferAssertTest/main.d

And the closest thing I have to an API reference at this point:

http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/util/deferAssert.d

(BTW, contrary to the names, deferAssert and deferEnsure don't actually 
defer anything other than throwing the fatal assert exception) 


Reply via email to