UnitTest and visual D

H. S. Teoh hsteoh at quickfur.ath.cx
Thu Feb 23 20:11:42 PST 2012


On Thu, Feb 23, 2012 at 09:28:07PM -0500, Jonathan M Davis wrote:
> On Friday, February 24, 2012 03:12:08 Chris Pons wrote:
[...]
> > Also, what should be in a unit test? Test cases to make sure
> > certain functions/classes are working as you intend them to?

Pretty much. The idea is to put stuff in there to check that your code
actually does what you think it does. Especially useful are tests that
check boundary conditions (i.e., corner cases, like empty input, input
which is 0, off-by-1 input, null input).


[...]
> But regardless, the idea is to use unit tests to verify that your code
> works how it's supposed to and fails how it's supposed to (e.g. when
> certain input should result in an exception being thrown)

For which the assertThrown template is very useful:

	unittest {
		// Instantiate an object of the class you're writing
		auto o = new myClass;

		// Make sure an exception is thrown when you try to do
		// something illegal.
		assertThrown!Exception(o.parse(illegalInput));
	}

The template basically runs o.parse(...), and if it throws an Exception,
then it catches it and continues running the unittest. However, if
o.parse(...) returns without throwing an Exception, then the template
will throw a unit test failure exception.


> so that you know not only that your code works currently but that your
> code continues to work when you make changes to it in the future.

This is one of the big benefits of unittests. By putting in test cases
that ensure your code does what you think it does, when you make a
change in the future the same test cases will tell you if you also broke
a previously working feature.


> It makes for much more robust code and often actually increases the
> speed of development, because you end up with fewer bugs (since you
> catch them when you write the tests, which you typically do when you
> write the code).
[...]

One thing I absolutely love about D unittests is that they're so dang
easy to write that you really have no excuse not to write them. Which is
the point, because most programmers in principle agree that unittests
are good, but they don't actually write them because traditionally (1)
unittests are external to the code you're writing, so there's the effort
of putting your current code on hold, switching to a different
directory, and adding a unittest there, then switch back. (2) They're
often in a different language, like Python or Expect, and it's mentally
taxing to keep switching back and forth between languages in the middle
of your coding session. (3) They have to be run separately, which most
programmers are too lazy to do. All of these, together with tight
deadlines, often result in no unittests or outdated unittests.

In D, by building unittests into the language and allowing unittest
blocks pretty much anywhere in the code (except inside a function), as
soon as you think of a corner case the complex algorithm you're writing
might want to handle, you can just stick it in the unittest block next
to the function and keep going. Often I find that before I even finish
writing a function, I've already written 2-3 unittests for it, and after
I finish it, I add a few more. By the time I actually run the program,
the new code already has a stringent set of tests that will quickly
catch any obvious bugs.

Then if your tests missed some test case that you later discover to
cause a bug, you just add it to the growing list of unittest blocks, and
then any further changes after that will always run that new test,
ensuring that the bug will never come back again.

D's unittests also never stagnate and get outdated: once you compile
with -unittest, your program will refuse to run until you fix the bug
that caused unittest failure. It's good motivation to actually fix the
bug instead of saying "I'll do it later", which often means "it won't
get done 'cos I'll forget by then".


T

-- 
"Uhh, I'm still not here." -- KD, while "away" on ICQ.


More information about the Digitalmars-d-learn mailing list