Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

C/C++

Counting Array Elements at Compile Time


Unit Testing

One important application of initializer lists is in defining cases for automated unit testing. Consider the testing of the addition operators for a new string class, xstring. Listing Two shows one way to write the tests. The ASSERT is meant to represent whatever macro or function the unit-test framework uses to express test assertions. Using initializer lists to set up a table of test data has two advantages: First, the data is clearly laid out, separate from the actual test code; and second, there is no repetition of the code. This is particularly useful when each test case needs a few lines of setup, or when the data can be combined in multiple ways to generate extra tests "for free." For example, in Listing Two, the same data is used to test five different functions: Three forms of operator+ and two of operator+=. Similarly, for most numeric types (but not strings), if a + b == c, it should also be true that b + a == c, that a == c - b, and so on.

void test_addition_operators()
{
   struct Test_case { const char *a, *b, *sum; };
   Test_case cases[] =
   {
      //  a      b       sum
      { "abc", "xyz", "abcxyz" },
      { "abc",    "",    "abc" },
      {    "", "xyz",    "xyz" },
      {    "",    "",       "" }
   };
   for ( int i = 0 ; i != COUNTOF(cases) ; ++i )
   {
      Test_case& tc = cases[i];
      xstring a(tc.a), b(tc.b), sum(tc.sum);
      ASSERT(    a +    b == sum );
      ASSERT(    a + tc.b == sum );
      ASSERT( tc.a +    b == sum );
      a += b;  // operator+=(const xstring&)
      ASSERT( a == sum );
      a = tc.a;
      a += tc.b;  // operator+=(const char*)
      ASSERT( a == sum );
   }
}
Listing Two

It may look strange to define a struct right inside a function as I did, but it's perfectly legal C++. Using a local struct has the same benefits as limiting any other definition to a narrow scope. I am only using the struct in this one function, and defining it inside the function makes that immediately clear. It also saves you from having to hunt for the definition by putting it right at the point of use. It prevents namespace pollution, and as a result, saves you from having to invent new (and usually more verbose) names for a "Test_case."

Unit tests are really just a particular example of a general idiom for writing table-driven code. When faced with a repetitious series of operations, you can often drive out the duplication by extracting just the parts that vary, putting them into a table, then looping over the rows of that table. The table could be in a database or external file when needed, but putting it directly in code gives you a powerful combination of efficiency and clarity.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.