Going to the mall is sort of an interesting business. I'm not generally a shopper, per se, so when I got to a mall, it's usually to get to a store, get what I want to buy, and get out, preferably without snapping at anyone or getting lost along the way. Malls aren't really set up to facilitate this. Take a look at a fairly typical mall layout:
There are multiple levels, multiple entrances, different hallways, different orientations, and a mixed numbering/naming/symbol system. It's confusing.
That sounds a lot like a modern system, doesn't it? A modern piece of software has modules, classes, mixed naming/constants/variables, different interfaces, and multiple access points to each logical entity. It's confusing.
And somewhere in all of this is the module we're looking to exercise, and the problem we're looking to track down. So, our goal is to track down this problem or to exercise this module. Our goal is also to get in and out as cleanly and quickly as possible.
We need to find the mall door that provides the most direct route to the module (or store) we want. Thinking not only about our task or problem, but also thinking about how we get there will help us:
- reduce our steps to reproduce
- decrease setup time
- improve the reliability of hitting the problem we're looking for (especially if it's a race condition or a deadlock)
So, how do we do this?
The actual solution to the mall door problem will be custom to your system. However, there are some principles that can be applied to a given module or area under consideration. Consider the following questions. At the point where you can answer "yes", you've achieved your goal of finding the closest mall door to your behavior. You win!
- First, can the module be addressed directly? Are there unit tests, an exposed API or other means of access? Does this direct address show the problem or behavior I'm looking for?
- If not, what other module might be interacting? Can I address just these two modules? Are there system tests, mocking, an API or other means of access? Does this show the problem I'm looking for?
- If I can't get the problem or behavior with two modules, it's time to try three. Can I get any three modules to show the problem or behavior?
- If I can't get the problem or behavior with three modules, then I'm looking at a system problem. So let's start from the outside and start throwing things away. Consider the system, and eliminate any APIs or entry points that do NOT show the problem. Keep throwing things out until the problem or behavior goes away. Then back up a step, and there's your mall door.
The goal is to approach a problem from its closest entry point. Over time, this goal will help make you check your assumptions about entry points. If getting to any problem or behavior has to be done with the entire system, well, that's about like having to walk all the way to one end of the mall to get inside, only to have to walk most of the way through it to get to your store. That walking is wasting time and wasting effort. Consider putting in a side door. Maybe the side door is a new testing interface. Maybe it's a mocking framework. What specifically it does will depend on your system. The point of finding the mall door is to consider how you can address components of your system in the most efficient way that still produces results, even if you have to change your components over time to do so. We call these testability requirements, and they're great changes to make. You won't find them until you start looking, though, so go ahead and seek the closest mall door.