Monday 14 January 2008

DSL for CppUnit tests

It's amazing what activities can one invent, just to have something to do but learn...
I've just written an external DSL to ease writing CppUnit tests. It's not finished, but it works.

There is one thing I particularly hate about CppUnit: you have to name every test in fixture at least twice - once when it's created, and another time when it's added to the suite. OK, it's C++, we don't have reflection to do this stuff automatically, preprocessor is to dumb to fix it too... but it still sucks. It's repetitive and error prone. And you can end with tests that are never called, because you have forgotten to add them to suite.

Blah. I think I'm clear.

I wanted to have something simple - generated code should be very similar to our source - tests bodies themselves should be just copied intro right places and so on. No full-blown C++ parsers... no C++ parser at all. Just something that is a little more than preprocessor macros.

And here it goes:

@includeHeaders

@beginFixture TestSum
Sum *sum;
@setUp {
sum = new Sum();
}
@tearDown {
delete sum;
}
@test "empty sum of nothing should be zero" {
CPPUNIT_ASSERT_EQUAL(0, sum->getResult());
}
@test "simple sum of 1+2+3" {
sum->add(1);
sum->add(2);
sum->add(3);
CPPUNIT_ASSERT_EQUAL(6, sum->getResult());
}
@endFixture

translates to

#include <cppunit/TestCase.h>
#include <cppunit/extensions/HelperMacros.h>

class TestSum: public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE( TestSum );
CPPUNIT_TEST( empty_sum_of_nothing_should_be_zero );
CPPUNIT_TEST( simple_sum_of_1_2_3 );
CPPUNIT_TEST_SUITE_END();

public:
Sum *sum;
void setUp() {
sum = new Sum();
}
void tearDown() {
delete sum;
}
void empty_sum_of_nothing_should_be_zero() {
CPPUNIT_ASSERT_EQUAL(0, sum->getResult());
}
void simple_sum_of_1_2_3() {
sum->add(1);
sum->add(2);
sum->add(3);
CPPUNIT_ASSERT_EQUAL(6, sum->getResult());
}
};

Simple as that.

Mercurial repo.

Time to finish this longish post before it took me more time to blog about it, than to actually write it...
cut!
My first post on my first blog is finished. Applause!