Stuff they taught in Kindergarten… The “D” in TDD

“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.)

Another misconception:

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.

Things they never taught in Kindergarten

I wish I would have paid more attention when I was 5. I was too preoccupied with the crayons, the PB&J sandwiches and the red cape that the little boy, Quinn, always stole during playtime. I wanted to wear the cape! I wanted to be Superman once in a while! why did he never share? Hi, I’m Cliff. You’re here because you’ve been traumatized in pre-school and beyond. I’m here because I feel your pain…

I learned several things today after hours of painful research. These are things I’m certain they covered in Kindergarten while I was off trying to impress the only other black person in my class (school?) who happened to be a girl. (Yes I had a kindergarten crush…) These are things they probably explained in detail but I was too busy making sand angels by the swing set. These are things that are critical to my success as an engineer, but now I struggle to learn them in my later years. Here’s a few lessons I learned the other day after much trial and error.

Virtualbox Networking

Setting up shared Wifi networking in Virtualbox from an OS X host to a Windows 7 guest is EASY if you were alert shortly after nap time. I’m sure my teacher covered the part where you have to use NAT (Network Address Translation) in your coroporate network unless your overhead wifi routers support bridging. I spent several hours trying to use a bridged configuration while my guest OS was not getting a valid IP only to find out that the in office wifi routers don’t support the type of bridging that Virtualbox was trying to accomplish. I only discovered the issue was related to the routers after connecting my iMac to my iPhone where bridging magically worked on the first try.

You don’t need a bridge!

I had trouble setting up shared folders in Virtualbox (as I always do after initially setting up any VM) so I took to Google. Don’t believe everything you Google! I lost 2 hours because an online tutorial clearly explained that you have to use bridged networking to enable shared folders. THIS IS A LIE!!! My shared folders were not working because of the following point…

Shared Folders

Setting up Shared folders in Virtualbox is a breeze if you take your head out of the lego box long enough to hear Mrs. Marzie, the Kindergarten instructor lecture the room. She clearly would have explained that one should plug in the guest additions CD image after installing the OS before even ATTEMPTING to setup shared folders. (Good ol’ Mrs. Marzie, she always knows what’s up!) IF you want to do anything other than look at the default OS logo or play solitaire then your very next step after installing the OS is to install the guest additions!

You need Java, Python and Visual C++ to do anything reasonable with Electron on Windows

If you are working on a NodeJS or Electron project which is anything more than basic you will need to download the entire internet onto your 256GB hard drive then press build. I’m exaggerating slightly but this is something I intend to write an entire epic series on as it applies to more than just NodeJS projects. Say you want to checkout a project on a brand new laptop (Windows or Mac). You’ve cloned the source and you run the build. The thing that happens next should be filmed… separately… for each developer that undergoes this process. It’s actually good material for a comedy show because the result is so unique and random. In some situations, like mine, you’ll spend hours Googling for separate tools and/or versions of tools. In other situations you’ll spend hours uninstalling separate tools and/or versions of tools. The problem is the developer who created the software probably uses a myriad of tools and dependencies which have accumulated overtime. These dependencies will not be present on a new machine and many will have been updated overtime since the software was first created leaving you with the chore of chasing down approximate matching versions.

My dilemma finally ended with me in a position to partially build my project but the struggle continues. Hit me up if you have any stories from Kindergarten to share!