Thursday, August 13, 2009

How MbUnit helps not violating DRY

When I was on a .NET user group meeting in Karlsruhe about TDD the speaker (speaking nicest bavarian dialect) created a unit test and did the unbelievable: He marked the 15 lines of code that made up the first test pressed <CTRL>+<C>, moved some lines below and pressed <CTRL>+<V> and changed some values of the test.

The audience was uhhing! Several of the listeners were wearing the CCD arm ring and could not tolerate a violation of the DRY principle.

Indeed Unit Test code must be written and maintained with the same care as production code.

MbUnit supports a very neat feature that helps keeping the DRY principle: [RowTest]

Instead of writing many TestEquals derivates you simply call the function multiple times with the Row attribute...

[RowTest]
[Row("03000000010000000000110101000063","","03000000010000001100110101000023","", false)]
[Row("03000000010000000000110101000063","","03000000010000000000110101000063","", true)]
[Row("03000000010000000000110101000063","name","03000000010000000000110101000063","", false)]
[Row("03000000010000000000110101000063","","03000000010000000000110101000063","name", false)]
[Row("03000000010000000000110101000063","name","03000000010000000000110101000063","name", true)]
[Row("03000000010000000000110101000063","name","03000000010000001100110101000023","name", false)]
void BarcodePatternTest::TestEquals(String^ barcode1, String^ realName1, String^ barcode2,  String^ realName2, bool isEqual)
{
 CBarcodePattern patternA((LPCTSTR)CString(barcode1),(LPCTSTR)CString(realName1));
 CBarcodePattern patternB((LPCTSTR)CString(barcode2),(LPCTSTR)CString(realName2));

 Assert::AreEqual(isEqual, CBarcodePattern::Equals(patternA,patternB));
 Assert::AreEqual(isEqual, (patternA == patternB));
 Assert::AreEqual(isEqual, (patternA.Equals(&patternB)));
}

2 comments:

  1. That is clearly similar to what PEX (http://research.microsoft.com/en-us/projects/pex/) calls Parameterized Unit Testing.

    Personally, I don't think attributes should be used for parameterization. That should be separated, so different sources can be used, including fuzzing providers.

    ReplyDelete
  2. I've been looking at PEX only on Channel9. Do you know if you can easily use PEX with C++/CLI?

    What I like about the embedding of attributes is that it helps me with KISS (Keep it simple - stupid).

    ReplyDelete