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 ▼


Static Testing C++ Code

Assume you have just written a beautiful function library. You could have used any programming language, but the library appears to other programmers as a sequence of functions callable by a program written in C (or in languages that conform to C-like function calling conventions). But before delivering it to users (who are application programmers themselves), you want to be confident about the library's correctness. Consequently, you write a program that uses the library. However, that program presumably won't invoke every function in every possible way. So to guarantee reasonable quality, you need to write a testing program that invokes the library functions, passing a variety of possible parameter values and checks if the outcome matches expected results.

The testing program can be written in a different programming language, provided it interfaces with the library's functions. Because a buggy function could crash a program, you could divide the testing program into several small programs and launch them sequentially from a script. If a program then crashes, the script can proceed to the next program.

Exception-Raising Libraries

Now assume that your library isn't a simple C function library, but rather a library that exports functions or classes usable only by C++ code. In addition, exception-handling issues must be considered. Actually, the C++ functions to test could raise exceptions, both expected and unexpected. The specification of every function can (and should) declare which exceptions may be raised while executing such functions.

For example, if I call a function passing as a parameter the name of a nonexistent file, I could expect that an exception of a specific type is raised by that function. And if I pass the name of an existing but unreadable file, an exception of another type is expected. Finally, if passing the name of a readable file, no exception is expected. Here is the code:

try {
} catch (file_not_found_exception &e) {
} catch (...) {
    failure("unexpected exception");
try {
} catch (file_unreadable_exception &e) {
} catch (...) {
    failure("unexpected exception");
try {
} catch (...) {
    failure("unexpected exception");

To properly test the library's exception-raising feature, every function call in the testing program must be put in a try block. After the calls for which a specific exception is expected (file_not_found_exception or file_unreadable_exception), a catch block for the expected exception type must be put. And for every call, a catch-all block must be put after the possible specific catch block to ensure that every unexpected exception is handled.

There are several open-source frameworks—Boost.Test, CppUnit, CppUnitLite, NanoCppUnit, Unit++, and CxxTest, among others—that facilitate the development of automatic testing programs of C++ modules.

Libraries That Can't Be Compiled

A testing issue rarely considered by textbooks and testing frameworks is this: "Are you sure that in using your library, the application program will be correctly compiled and linked when it should?"

When you use libraries written in C, this isn't a big issue—library header files clearly define which functions are exported by the library, and it is always clear which function is called by a statement of the testing program. Therefore, in the testing program every library function is called at least once. If you can smoothly compile and link the testing program, then you can be confident that build problems should not arise for library users. This is a reasonabe assumption of developers who create libraries for C, Pascal, Fortran, or other languages according to the interfacing standards.

In fact, even in those languages, there can be problems regarding name collisions. With C++, these problems are avoided by using namespaces. Nonetheless, some complications arise in C++, mainly due to templates and overloaded functions.

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.