Black Box Testing

Read time: 9 minutes (2405 words)

We have introduced the concept of unit testing parts of your code as a way to gain confidence in your work. Testing is a big topic, and there are tons of opinions on how to do testing properly.

We can test some mall part of a program, usually something like a method (or function). Catch gives us a simple tool to create these tests. But exactly what are we testing?

We are testing the interface to the function, not the code contained inside. Testing, at least in some circles, should focus on the external view of the unit being tested, not how that unit does the work inside. That way, you are free to change the implementation of the unit, and the tests remain unchanged.

When we set up a C++ class, we create an external interface to some object based on the public attributes and methods we create. Those aspects of the class are proper candidates for unit testing.

The class may well have other methods and attributes that are not publicly exposed to users of the class. We should not test those parts of the class, since we might want to modify the internal aspects of the class later on. The key idea here is to keep the tests sound, and focused on the specification of the class, not the implementation of the class.

So how do we confirm that the internal implementation is working properly.

Many testing advocates say that you do not test that! Instead, you prove that the code functions properly from that user perspective. If those tests pass, the internals must be working properly.

Testing Implementation

There are ways to sneak around the private barrier that hides things from users of your class. For example, we can st up a friend class that can bypass the private restriction allowing access to private variables and methods, then test through that friend class. While this will work, is sets up tests that will need to be modified if that internal structure changes.

Phew, what is a new tester to do?

In a beginning C++ class, where the goal is to get students used to testing, I favor using the trickery to get around the private barrier. This is done solely to get the students to think about testing every function they write. Especially during their early programming courses, it is important that the code they right is “correct”, even if it ends up in a private part of their class.

Once they get testing into their normal work pattern, we can back off and focus on the public interface, not the implementation.