This Is Why We Mock, Part II

In the previous episode, I claimed that our temperature control application is utterly untestable. That’s quite a broad statement, so before going any further, I’d like to clarify what I really meant.

You can always load our code on an embedded device (like a Raspberry Pi) and attach an appropriate physical temperature sensor as well as a real heater. With the help of an additional external thermometer and an additional external heater you can create various conditions and check whether our system behaves as expected. This is called system testing. Even though it’s ultimately necessary, system testing is tedious, time-consuming, error-prone, expensive, depends on hardware and what-have-you. If you discover a bug at this stage, you have to repeat the whole manual procedure again (and again and again).

When I, as a developer, talk about testing, I generally mean unit testing. Unit testing can be done at your desk, on your PC, without external hardware, within seconds. Even better, it can be fully automated and parallelized. So to be more precise: our temperature control app is utterly impossible to unit-test.

What actually is the unit that we want to test? Our focus is on the control logic, so the class “Controller” is our unit-under-test (UUT). We want to verify whether all logic paths are covered and whether they produce the expected output (heater turned on or off).

In the remainder of this post, I’m going to rewrite the code such that unit testing becomes possible. Let’s go!

One major nuisance with the existing code is that it contains an endless loop. It’s impossible to look inside the loop from a unit test-case. So in a first step, I’ll factor out the meat of the loop, the code where the action takes place.

As you can see, all the loop in “run” now does is invoke a method called “step”. “step” contains the control logic and we have now a much better grip on it. By repeatedly calling “step” from within our test cases we can single step through the code logic and check after every step if we get the desired effects. (Therefore, I like the method name “step”, what about you?)

The fact that we aggregate the sensor and the heater as members of our controller is a gross violation of modern software design principles, as we make our code (the controller) depend on concrete implementations (classes). If we instead depend on interfaces, we can substitute one implementation (a hardware temperature sensor) with a fake/mock temperature sensor (more on mocks later), as long as they both adhere to the interface. So let’s get rid of concrete classes and introduce interfaces:

Our familiar hardware sensor implements this interface, just assume that the actual implementation hasn’t changed from the first episode:

We proceed in a similar fashion with the heater:

Finally, we can rewrite the controller code such that it works against abstract interfaces instead of concrete implementations:

All dependencies (sensor, heater) are passed via so-called dependency injection as interfaces to our controller class.

Obviously, in order to work as before, our application still must depend on concrete classes. But only in a single place — the main function:

Our code hasn’t changed a bit in functionality, it behaves just as before. But contrary to the initial design, it’s now utterly testable, er, unit-testable, I mean.

In the next episode, we’ll talk about mocks and finally implement the unit tests. Stay tuned!

Previous episode

This Is Why We Mock, Part I

Everytime I watch one of those “This is why we ride” videos, I immediately want to jump on my bike and head for some twisty mountain roads. What’s more, even people who don’t have a driver’s license also feel a strong urge to jump on a bike.

I wrote this post in a similar spirit, hoping to convince C++ developers that unit testing with mocks is both, necessary and fun. My main focus is presenting a case for using mocks, since I regularly meet even experienced coders who are not familiar with mocks. If you’re not familiar with mocks, it’s a clear sign that you have never really unit-tested your code. It’s that simple! You might have unit-tested some free-standing library or algorithm that you wrote, but when an application consists of multiple interacting components implemented by different people, there’s no way for you to test your component in isolation without linking-in the components you depend on. If you do so, you’re not doing unit testing. You’re rather doing integration testing. And what do you do if the components you depend on are still under development? Do you postpone your work and wait until they are fully done? What if some components are hardware-dependent and only available on the target platform? Do you leave the comfort of your host platform and execute your tests only on the target platform? No! What you do is sprinkle some “design for testability” over your code and test against mocks. Suck it up!

Let’s do an example, a very basic temperature control application. It consists of a heat sensor, a heater, and the controller. The controller is a simplistic on-off controller which reads the current temperature from the sensor and compares it against a target temperature. If the temperature is below the target temperature, the controller turns the heater on, if the temperature is above the target temperature, it turns it off. To make it a bit more interesting, I added another requirement.

To avoid frequent on/off toggling of the heater around the target temperature point, the controller supports so-called hysteresis, a temperature range below the target temperature in which the controller doesn’t turn on the heater even though there is a deviation from the target temperature. Here’s an example: if the target temperature is set to 23 degrees and there’s a hysteresis of 2 degrees, the controller will not turn on the heat if the current temperature is 22 degrees. Not even if the current temperature is 21 degrees. It will, however, turn on the heater at 20 degrees (or less) as this is outside the range of the hysteresis.

But wait, there’s another point to mention. The temperature sensor provides a status, which tells if the temperature reading can be relied upon. If the sensor status is “bad”, the measurement must be ignored. If the status is “bad” for two times in the row, it means that the sensor is broken and the controller application shall (for the sake of safety) turn the heater off and exit.

If you like, you can pause here and think about how to implement and test this application.

Done? Here’s my naive implementation:

Does this code implement the requirements correctly? I don’t know for sure, but I assume it does. Do you agree?

Correct or buggy, it’s hard to agree. But we can easily agree on one thing: this code is utterly untestable. In the next part, I’ll refactor it such that it becomes one hundred percent testable, which allows us to move from correctness assumptions to knowledge. Stay tuned!

Next episode

Accessing Private Members with the Attorney Pattern

“C++: Where all your friends have access to your private parts.”
— anonymous

For good reasons, class designers usually keep implementation details out of the public interface. In object-oriented programming, this is called “encapsulation” and is generally considered a good thing. However, when unit testing such a class, it’s sometimes desirable to access private members of a class to verify that a class indeed works correctly, not just on the “surface” (i. e. the public interface). As an example, take this contrived C++ class that we want to develop our unit tests against:

If we attempt to access ‘privateMethod’ or the ‘values’ array from our tests, we’re out of luck, since they’re both declared private.

There are several known solutions to work around this problem:

  1. Simply don’t use the ‘private’ and ‘protected’ access modifiers; declare all members ‘public’. While this is common practice in the Python community, it’s shunned by the C++ community.
  2. When the unit test build runs, let the preprocessor substitute all occurrences of ‘private’ (or ‘protected’) with ‘public’ by specifying the substitution as a command-line argument to the compiler (i. e. -Dprivate=public). While this is quite pragmatic and doesn’t require any code changes, some folks refuse to accept such behind-the-scenes preprocessor trickery.
  3. Instead of directly using ‘private’ and ‘protected’ access modifiers in your class definition, use your own preprocessor symbols like ‘PRIVATE’ and ‘PROTECTED’. During a regular build, these symbols are replaced via the preprocessor with ‘private’ and ‘protected’, respectively; during a unit test build, they both are expanded to ‘public’. While this approach is more transparent than the previous approach, it’s not at all pleasant to look at and there’s no syntax-highlighting support by editors/IDEs.
  4. Access the inaccessible members via a trusted entity, an attorney. In the remainder of this post, I’ll explain this approach.

Generally speaking, one risk of making many private details easily accessible during unit test builds is that unit test developers are seduced into making their tests too dependent on low-level implementation details, which makes future refactorings much harder. The attorney pattern also gives you low-level access but in a much more controlled fashion; it forces you to be explicit about what you want to access:

ClientAttorney is basically a limited, forwarding proxy around an existing Client instance that makes part of Client’s implementation details publicly available. For this to work, ClientAttorney obviously needs to be declared a ‘friend’ in Client’s class definition:

While some folks complain that this requires too much typing, proponents emphasize that this exactly the strong point of the attorney pattern: in order to be able to do something shady you have to invest a little effort, which automatically reduces the amount of shadiness that you introduce into your unit tests.

Personally, I like this explicit approach, but I never liked all the boilerplate. It’s not just tedious to type and maintain: If the signature of a Client method changes subtly (say a parameter changes from ‘int’ to ‘double’), inconsistencies can remain dormant for quite some time until suddenly problems arise. So in my tests I use this templated variant of the attorney pattern:

Then, in my unit testing project, all I need to do is this:

By employing subclassing and ‘using’ declarations, I can redeclare existing private base class (Client) members as public without having to worry about future type or signature changes. This solution still forces developers to be explicit but avoids most of the tediousness and is at the same time less error-prone.

Bug Hunting Adventures #15: Hex String Entanglements

“Don’t be drawn into any web of entanglement created by others.”
― Steven Redhead, Life Is Simply A Game

The following routine is from a real-world project. It’s supposed to convert binary data into a printable C-string of hexadecimal digits. Even though the developer diligently wrote some unit tests, he got complaints from his fellow coders a few days later. Can you find what’s wrong with it?

Unit tests:

Solution

Circular Adventures VIII: The Eternal Quest for mod-like Behavior

“A circle is a round straight line
with a hole in the middle.”
— Mark Twain

In circular situations, we often wish to employ the mod operator to achieve “wrap-around” at both ends of a linear system to mimic a circular system:

Achieving clockwise wrap-around (from n to 0) usually poses no problem:

The % operator is the compiler vendor’s approximation of the mod operator. It ensures that values which exceed n wrap-around nicely:

Alas, most operator % implementations are not so useful when it comes to counter-clockwise wrap-around (from 0 to n):

If index – 1 becomes negative, we likely get negative results — which is far from what we desire:

To readers of this column (part I in particular) this is of course old hat. They know that you can’t trust the % operator when negative operands are involved. Circular coders often work around this shortcoming like so:

Not nice, but no big deal either, you probably think. But what if you need a function that advances an index in either direction, depending on the sign of the offset:

Now this looks disgusting, this is a big deal! And all just because our wretched % operator doesn’t behave like it should. Remember, if it did, we could simply write:

Did you notice that our convoluted circular_advance function actually contains a bug? No? Here’s a hint. The bug is in this line:

What happens if the offset is larger than n? Answer: the expression n – offset will underflow producing a wrong result. That’s why we would have to write this, at least if we wanted to be 100% correct:

which makes the code even uglier. But do we really need to support such large offsets? If we don’t (which is almost always the case in circular scenarios) and can live with offsets whose value is less than or equal to n, we can simplify circular_advance significantly. Here’s how.

We know that adding a multiple of n to the dividend x doesn’t change the result of the modulo operation:

If we include an arbitrary offset, we get this:

This allows us to turn negative arguments to operator % into positive arguments by adding i*n, without changing the result. Further, if we ignore cases where the offset value is greater than n, we only have to add 1*n to enforce a positive argument to operator %. Here’s an example:

Since all operands are positive, we can use 6 % 8 to compute -2 mod 8. Equipped with this knowledge, we can eradicate the ugliness and circular_advance boils down to this:

If we apply the same technique to the ring buffer’s original ring_buffer::size method from the last installment:

we get a simple branch-free solution:

which can be optimized easily by the compiler, especially if BUFSIZE is a base-2 number.

So here’s the takeaway. To get efficient, branch-free mod-like behavior for positive divisors n:

If n is a base-2 number, use bitwise-AND instead of the % operator:

If there’s only clockwise wrap-around (ie. a >= 0), % works just fine

If a is either positive or negative, but |a| is <= n, add n to the operand before applying the % operator:

More circular adventures…

Flashme

“It is the flash which appears,
the thunderbolt will follow.”
– Voltaire

Flashme is a flashcard program for command-line lovers, just like me. To avoid repeating myself, here’s the introduction from the GitHub project’s README file:

“I felt compelled to write flashme because I couldn’t find anything like it. While there are many freeware flashcard programs out there, none met my chief requirement: it must be fully operable from the command-line. My next most important requirement was that cards must be kept in plain text files (I call them “deckfiles”): I want to be able to diff, grep, and edit deckfiles with standard Unix command-line tools and editors. Binary file formats, including zipped XML files, are a nuisance and make it difficult to store flashcards in version control systems.”

I’ve used flashme extensively (and successfully) for more than a year to learn English, Linux command-line options, vi hacks, and much more. I think the time has come to release it to the public.

Share and enjoy!