The Pitfalls in C++ Unit Testing

DZone 's Guide to

The Pitfalls in C++ Unit Testing

In this article, I’ll discuss the most common pitfalls of the C++ programming language when unit testing.

· Performance Zone ·
Free Resource

Recently there has been a surge of interest in C++ unit testing. C++ unit testing has not been common in C++ development in the past.

Although C++ is a kind of programming language that fits well with unit testing, several complexities require extra care. In this article, I’ll discuss the most common pitfalls.

unit testing for C++

The rising interest in C++ unit testing

Let us begin with the Legacy code

After COBOL and FORTRAN, C++ is probably the next language in turn to hold most of the legacy code. Developers are usually reluctant to subject legacy code to agile development solutions. Maintaining legacy code is a hassle by itself — how would one dare to write unit tests for it? 

Writing stable unit tests for legacy code requires some skill and a lot of patience, but even then, there is no easy way to do it. The reason for it being complicated is that the code wasn’t designed for testability and hence can’t be unit tested directly until refactoring is done. 

However, there’s a catch-22 here: we need to change the code-> there are no tests->it wasn’t designed for testing-> it needs refactoring to add tests-> we can’t refactor without tests-> we are back at the starting point.  

According to Michael Feather’s book, “Working efficiently with legacy code,” the algorithm to resolve this unfortunate paradox is as follows:

  1. Identify change points
  2. Find test points
  3. Break dependencies
  4. Write tests
  5. Make changes and refactor

Feather’s book is highly recommended for learning about unit testing legacy code.

Enough about legacy code. Let’s talk about Slow builds

The build process for C++ is more complex, demanding and time-consuming than for other languages. The most significant reason is that the build process involves compiling and linking. Other reasons include the heavy usage of C++ libraries.

A complete build cycle might take hours which reduces the will of developers to implement unit tests. Even with a goal of continuous unit testing, this might lead to infrequent testing and eventually giving it up completely. 

Another complicating factor in C++ unit testing is the lack of powerful Mocking libraries. Many of these mocking libraries in C++ are limited compared to equivalent libraries in other languages. For example, mocking concrete classes, non-virtual and static methods, private fields and private methods is rarely possible for most mocking libraries in C++, whereas in other languages, mocking libraries are not as restricted. Instead, mocking libraries in C++ expect you to design your code for testing. 

Lastly, the misconception of “manual tests are unit tests” in C++ counts as another pitfall. “Manual unit testing” is impossible. There is no such thing. Unit testing is defined as testing small units of code in isolation which is impossible to do manually. Developers sometimes confuse unit tests with integration tests: manual testing can be done on integration tests only.

c++, c++ pitfalls, legacy code, performance, unit testing

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}