Driving Development Of Tests

During the development of Mimicc I shared the tool with a colleague of mine who joked that I should post it on Hacker News so we could watch the inevitable flame war that ensues. While he certainly intended that to be hyperbolic, the related topics of unit testing, mocking, and Test-Driven Development have a way of bringing out some very strong feelings from otherwise mild-mannered people. What is, after all, the “right” way to test?

This short post is not going to attempt to answer that question. In fact, this author questions whether there exists a unified answer to that question at all. Real software is complicated, and when it comes to making design decisions, context trumps dogma most of the time. Does it matter if we’re talking about C++ or some other language? Does it matter how close to the hardware it is? Does it matter how big the team is? What our Devops infrastructure looks like?

At the end of the day what is most important is not how we test, but that we test. Of course that’s not to say that the how question is irrelevant or unimportant, but that the question of how we test must necessarily work in service of the directive that we test. Most engineers reading this will agree with this statement as almost self-evident. So why then don’t we test more? What are the barriers to writing tests?

Of course there are many language, platform, and environment-specific answers to this question, but there’s one that holds true universally: complexity. Complexity is the enemy of testability, and useful software is intrinsically complex.

Mimicc is fundamentally a tool to reduce complexity. In fact this is true of all mocking frameworks. What sets Mimicc apart is:

  1. It’s designed for software written in C and C++
  2. It aims to reduce complexity while simultaneously imposing as little dogma as possible.

Avoiding dogma in this context can be further defined as minimizing what is sometimes called “test-induced damage” to production code. In other words: Mimicc attempts to make your code more testable without you having to change the way you write it. This is particularly relevant in a language like C++, which has a very large toolkit of features to draw from. It’s very easy to write code which is not only extremely complex, but extremely difficult to test. Most professional organizations manage this by reducing the usable feature set available to engineers. Others simply accept that the loss of testability and coverage is a fair trade-off for the power of the language feature in question.

The designers of Mimicc have strived and are continuing to strive to build a tool which injects itself as intelligently as possible into your workflow. This is reflected in the name “Mimicc” which is intended to convey not only that it creates mock code which “mimics” the production code you’re trying to eliminate for complexity control, but it also “mimics” the behavior of your compiler. We believe the end result is something that has the best possible chance at enabling you to write more tests, and spend less time maintaining them.

Martin Fowler writes on the opening of his website that “software development is a young profession, and we are still learning the techniques and building the tools to do it effectively.” This, almost more than anything else, summarizes why Mimicc exists, and why it has to continue to grow and evolve if it’s going to drive the kind of software quality we all want to see in our professional and personal projects.