Jay Myers, Software Engineer
April 7, 2015
Conservation of momentum may be implied by Newton’s laws of motion, but it’s far from guaranteed in the world of software development. In this blog post, the author discusses what it means to use tests to drive your software development and what it can do for both your code quality and team velocity.
“Top Gear” is one of my favorite shows (the UK version, not the one filmed in the US). In every episode there is a segment in which a celebrity drives an ordinary car around the track, the lap times are posted and then ranked against the other celebrities participating in that series. I usually ignore this segment, as the other portions of the show are generally more entertaining, however I recently noticed something that resonated with me.
As the celebrities are watching the rerun of their best lap, eagerly awaiting their lap time to see where they’ve fallen in the overall ranking, they are often critical of their speed. The host routinely tells them that although it seems as though they’re going slow when they watch themselves, they are actually going much faster than they realize. In fact, it’s usually the laps that look the quickest and most exciting that turn out to be the slowest.
The exhilarating laps are generally full of oversteer and corners taken on too abruptly. While this is definitely more fun to watch, it results in a lot of wasted energy on the driver’s part, as they constantly have to work their way back into control to undo the damage done to their lap time.
What does this have to do with development? A lot, actually. When looking at the speed at which software is developed, it’s easy to miss the forest for the trees. Often times, as features are rapidly developed and new functionality is pumped out at a startling and exciting clip, it’s easy to assume that this speed will last forever. Sadly, this is almost never the case, and eventually momentum is lost as a team’s overall velocity begins to fall.
Why does this happen? It’s a consequence of not letting tests and requirements drive your development instead of grabbing the wheel and burying the gas pedal in the carpet yourself. Test driven development is the practice of writing test code before writing functional code. The test code asserts something about the functional code — some requirement or desired behavior that is currently lacking. This results in a failing test case, at which point the minimum amount of functional code required to satisfy the test is written. If necessary, the functional code is refactored and reshaped to increase its readability, modularity, cleanliness, and then the cycle is repeated. This cycle is referred to as red/green/refactor.
The software requirements drive the test code, and the test code drives the functional code. As functional code is written, it can easily be refactored because you can immediately re-run your test code and know that you have not changed the desired behavior specified by the tests. This allows you to safely make what would otherwise be potentially dangerous modifications, wide sweeping changes across your code base.
It is this freedom that is the key to true speed — quickly adapting to new requirements, since all that is needed is to add test cases that assert they are satisfied by your code. If the new requirements cannot be satisfied, you have the freedom to safely refactor your code. If your code has become confusing or unclear, you have the ability to simplify it without worrying that something is broken which was previously working.
Sounds great, right? So why doesn’t everyone do this? Simple — it’s hard work. It takes lots of discipline to do this when there is a deadline looming overhead. It seems much quicker to just drop all this extra work and simply write code that will satisfy the requirements. Developers are smart and they know how to interpret requirements and write code that will satisfy the needs of their users, but after several iterations of this rapid development, it’s likely velocity will begin to drop and the momentum you were so enjoying could slip away. The codebase in which you are working then becomes unstructured and unclear. If only you could inject some sense into it and restructure things to be more clear! But alas, you are without tests and cannot, without serious and expensive regression testing, be sure that things have not been broken as a result.
Now I’m not suggesting that this red/green/refactor methodology is the only way to move quickly – anything that ensures you are writing a sufficiently robust suite of test cases will allow you that. Even so, it is the most surefire way to make sure your tests are actually checking against all requirements. And having that safety net of tests below you is a requisite to truly blazing development speeds in the long run.
The real lesson is that when you are really going fast, it may seem like you are moving slowly. Don’t be disheartened if you feel this way — just sit back and let the tests do the driving.
Jay Myers, Software Engineer
April 7, 2015
Conservation of momentum may be implied by Newton’s laws of motion, but it’s far from guaranteed in the world of software development. In this blog post, the author discusses what it means to use tests to drive your software development and what it can do for both your code quality and team velocity.
“Top Gear” is one of my favorite shows (the UK version, not the one filmed in the US). In every episode there is a segment in which a celebrity drives an ordinary car around the track, the lap times are posted and then ranked against the other celebrities participating in that series. I usually ignore this segment, as the other portions of the show are generally more entertaining, however I recently noticed something that resonated with me.
As the celebrities are watching the rerun of their best lap, eagerly awaiting their lap time to see where they’ve fallen in the overall ranking, they are often critical of their speed. The host routinely tells them that although it seems as though they’re going slow when they watch themselves, they are actually going much faster than they realize. In fact, it’s usually the laps that look the quickest and most exciting that turn out to be the slowest.
The exhilarating laps are generally full of oversteer and corners taken on too abruptly. While this is definitely more fun to watch, it results in a lot of wasted energy on the driver’s part, as they constantly have to work their way back into control to undo the damage done to their lap time.
What does this have to do with development? A lot, actually. When looking at the speed at which software is developed, it’s easy to miss the forest for the trees. Often times, as features are rapidly developed and new functionality is pumped out at a startling and exciting clip, it’s easy to assume that this speed will last forever. Sadly, this is almost never the case, and eventually momentum is lost as a team’s overall velocity begins to fall.
Why does this happen? It’s a consequence of not letting tests and requirements drive your development instead of grabbing the wheel and burying the gas pedal in the carpet yourself. Test driven development is the practice of writing test code before writing functional code. The test code asserts something about the functional code — some requirement or desired behavior that is currently lacking. This results in a failing test case, at which point the minimum amount of functional code required to satisfy the test is written. If necessary, the functional code is refactored and reshaped to increase its readability, modularity, cleanliness, and then the cycle is repeated. This cycle is referred to as red/green/refactor.
The software requirements drive the test code, and the test code drives the functional code. As functional code is written, it can easily be refactored because you can immediately re-run your test code and know that you have not changed the desired behavior specified by the tests. This allows you to safely make what would otherwise be potentially dangerous modifications, wide sweeping changes across your code base.
It is this freedom that is the key to true speed — quickly adapting to new requirements, since all that is needed is to add test cases that assert they are satisfied by your code. If the new requirements cannot be satisfied, you have the freedom to safely refactor your code. If your code has become confusing or unclear, you have the ability to simplify it without worrying that something is broken which was previously working.
Sounds great, right? So why doesn’t everyone do this? Simple — it’s hard work. It takes lots of discipline to do this when there is a deadline looming overhead. It seems much quicker to just drop all this extra work and simply write code that will satisfy the requirements. Developers are smart and they know how to interpret requirements and write code that will satisfy the needs of their users, but after several iterations of this rapid development, it’s likely velocity will begin to drop and the momentum you were so enjoying could slip away. The codebase in which you are working then becomes unstructured and unclear. If only you could inject some sense into it and restructure things to be more clear! But alas, you are without tests and cannot, without serious and expensive regression testing, be sure that things have not been broken as a result.
Now I’m not suggesting that this red/green/refactor methodology is the only way to move quickly – anything that ensures you are writing a sufficiently robust suite of test cases will allow you that. Even so, it is the most surefire way to make sure your tests are actually checking against all requirements. And having that safety net of tests below you is a requisite to truly blazing development speeds in the long run.
The real lesson is that when you are really going fast, it may seem like you are moving slowly. Don’t be disheartened if you feel this way — just sit back and let the tests do the driving.