“T” stands for Teddy! That’s good enough for me! Oh Teddy, Teddy, Teddy starts with “T”! Hi, I’m Cliff. You’re here because you wanna figure out what the heck that first sentence is talking about. I’m here because I got side tracked reading an Uncle Bob article which led to my singing a parody of the “C” is for cookie, Cookie Monster jingle. I’m STILL supposed to be working through negative password validation in an Android app but I don’t think I’ll finish in time for a planned demo in 2 days. You might ask “Why am I singing the letter ‘T’ when my title places emphasis on the letter ‘D'”? I’m glad you asked!
I’d like to tell you a story. Once upon a time there was a software engineer who ventured into the land of frogs where everything was green. It was like St. Patty’s day all time which was cool because this guy’s birthday happened to be in the month of March which is a green month. (I never understood why the month of March is always colored green. I suppose it has something to do with the Irish like they all came from Mars and make excellent landscapers or something but I digress.) So this developer *ahem* engineer was living in bliss because there were all of these segmented bars filling up in this magical land, each of which was green. He wanted to share the beauty of this whimsical place with his co-workers but they were all like, “Ain’t nobody got tahm of’ that!” So he goes on living in his shamrock colored habitat for the rest of his life. The end.
Now ask me why did I tell that story? (Again, I like how you ask questions!) Well partly because I sometimes feel compelled to inject random nonsense in the middle of my posts for no apparent reason. However the parody roughly represents my first encounter with TDD, a practice which I am extremely fond of. I want everyone to share in my euphoria but some folks are just wired different I suppose. It’s this wiring that causes some to focus on the wrong letter of the practice. Here we finally arrive at the point. By the way, welcome to the next entry in a series I’m titling “Stuff they taught in kindergarten”. In this series I will cover topics I just learn or re-learned. These are the very same topics my preschool teacher, Mrs. Marzie, covered during my early years. I missed out because I was busy fighting over who gets to play with the Green machine during recess.
“T” is for TESTING. As an avid practicer of TDD I will be the first to tell you that you should never write tests. If you are writing tests you are doing something wrong! When I practice TDD I never write tests or any test code. I hate tests. I despise the word “test”! Ask me how I could feel this way and still actually be a TDD supporter? I’m not a TDD supporter, I lied all this time. I’m a wolf in sheep’s wool. I support the practice but discourage the idea entirely. Let me elaborate.
The word “test” triggers the part of the brain that pulls you away from the most important part of TDD. Check the title to understand where I’m going here. I’ve seen so many well meaning engineers steer wrong because they start to get excited about tests and writing tests and testing their code. (Uncle Bob hits on this point somewhere in the middle of his article and I promised myself I would emphasize this point as the very first part of my blog but I’ve failed miserably!) If you are testing then you are looking for bugs. You are looking for holes in your code and weaknesses. All of this makes absolutely no sense because it implies you have working code. (I need to do an entire other post on the term “working code” because it’s another one of my pet peeves.) When you practice TDD the way it is intended then you don’t have working code. You don’t have broken code. You just don’t have code, instead you have a DESIGN. (Ah, there it is roughly 640 words in and I finally hit the point, design.) With TDD you have a design that you iterate into code that reflects a specific use case. It’s the emphasis on “testing” that turns people away from the discipline of designing. It is the discipline of design that gives TDD its power. When you practice TDD you never write tests, rather you etch a design using a testing framework.
Before I get too far I want to address some misconceptions. In particular I need to disagree with one point Uncle Bob makes:
It’s true that TDD is not going to help you defend against things you didn’t anticipate.
Bob is well meaning and he wants to play nice with others but this is not entirely true. One of the major benefits of TDD is that you have the ability to incorporate use cases you didn’t anticipate into your design through loose coupling and better cohesion. Th most difficult thing you will ever do as a programmer is change code. When you encounter some use that was unplanned you have to make a change to your code to get it to adapt. If you don’t do TDD then I can guarantee that the change is going to cost more in effort than it cost to write the code initially. In many of these cases you build a work around to adapt to the new feature without actually changing the original behavior. If you do practice TDD then you have already established a predictable pattern of creating, changing, and removing code and the cost remains flat. That means it cost just as much to change existing code as it does to add new work-around code.
Getting back to what I said earlier, you don’t write tests with TDD. A test implies there is code with a potential flaw or weakness. With TDD you use a testing framework to express a particular use of code that has not yet been written. (That’s why it’s called “Test First” because you first code with the testing framework but you really aren’t coding a test you are coding the actual use.)
the way to address that is to work hard at anticipating as much as possible.
I don’t know why people think working harder is the answer to tough problems. It is actually the cause of the tougher problems. If you are working hard at something then there is a flaw in the design. Also anticipating as much as possible is the opposite of what I like to do. I anticipate only what I feel comfortable anticipating and let the detail emerge as my project matures. As an example, I’ll use this Android app I’m currently building. I stopped working on it about 4-5 months ago and intentionally left holes in my design. I was only concerned about the app paths and getting a prototype working. I recently resumed the project and was able to easily cover some of these holes as I explored new unplanned uses of the code. When I originally wrote the code I just didn’t feel like anticipating these uses because they weren’t important. Now that many have become important I am able to address them with a fresh perspective and solve them in ways I wouldn’t have thought of earlier. Had I anticipated these uses I would have written code that would not be as flexible. It’s hard to describe actually. It’s one of those “you had to be there and live it” kind of moments.
I’m not picking on Uncle Bob… I love his writing/articles, and I’ve unfairly taken a couple of his points slightly out of context to drive a broader point. The point is that writing tests and testing code is not TDD. Designing the proper use of code before you implement it is the core of the practice. This is, by far, my biggest pet peeve with TDD and people who try to explain or defend it. I honestly think we should abandon the word test in favor of something more definitive like “specify”. I like the practice of Specification Driven Design where you specify how you will use/invoke an object with a
test specification framework. Still its acronym, SDD, sounds too much like STD and could give the wrong idea. I wouldn’t want to announce I am giving a class on SDD or tell folks I got this SDD thing at work. They’d be all like, “fo’ realz??? Yo, keep ya’ distance!”
That’s all for this installment of stuff they probably taught in kindergarten. I’ll see you next time I get inspired to blab about something.