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.