Who struggles embracing unit testing?

Will unit testing "come back and slap us in the face?"

Today I want to share with you a blog post that I just loved reading over the weekend: “Why bother writing unit tests?” by Justin J. Moses.

Take a minute and jump to it… and then we can come back and talk a little more about what you have just read. (Go ahead… I’ll wait here.)

Thanks for coming back! First, let me start by saying I love hearing someone else’s history with unit tests.

The energy that Justin showed in writing about kicking and fighting his way into becoming an advocate for unit tests teaches me a lot about what people experience in adopting a new approach like unit testing.

A different story of unit testing

In the mid-90’s, in the advent of Java in the browser (think applets and Netscape Communicator), I was working as a consultant integrating testing methods into the development life cycle for Chrysler Corporation as part of their QS9000 standards initiative.

A colleague and I were building a software testing and certification lab, buying & developing custom tools for registering and certifying apps and designing processes for better requirements, traceability, regression, scale and load testing.

We had lots of toys to play with, but the one idea that resonated with me most during this period was that business requirements were getting transformed too many times before software delivery.

If anything could help us write better software it would be reducing those transformations and knowing that we ultimately tested what we wrote and that we wrote what our customer wants. Simple enough, right?

(By the way, across the cube wall from us was another little Smalltalk project for the Chrysler payroll folks… but that’s a story for another time… and perhaps one of the reasons I lean more toward XP… again, a story for another time.)

Some of the side effects of Test-Driven Development

So Test-Driven Development solved many problems for me. Closer linkage of requirements to tests, and the suggestion that if we preserve that linkage and stick to the scope of our tests… some really great side effects can show up for us, like:

  1. No gold-plating
  2. Successively refined coding, and not out of control
  3. Simpler code
  4. A discipline that supports true continuous integration (CI)
  5. Test failures (with rigorous CI) offer a laser-focus on what changed & who worked on it over a short time interval
  6. (and probably many more)

If the bar is green, the code is clean?

And with the release of xUnit frameworks to support building and automating tests it seemed to me like the answer to prayer! So I went into TDD and CI head-first, and therefore it’s good for me to carefully read and understand that not everybody has the same experience.

I make TDD and CI a requirement of my teams, among other practices… and so an understanding of the struggles people can face is also important if we’re all going to produce and write great software together.

What was your experience embracing unit testing… more like Justin’s or more like mine? Have you tried TDD or CI (not just an automated build/test process)? What struggles have you had? How did you cope with them?

“Producing” Software

What is it to “produce”, specifically in the domain of software? We speak of productivity in business all the time, so let’s start by linking productivity with “producing” and “production”.

The Theory of Constraints, a production system most often linked to manufacturing, uses three metrics – inventory, operating expense and “throughput”. Though the first two are not as obvious as they may sound (and are topics for other posts in the future), “throughput” is the rate at which a system produces “money” (or products we can sell, or software we can ship to a customer).

Now, you may remember I am a proponent of agile software development. There are some great philosophical parallels between ToC and tenets of agile, but one thing I want to focus on is what helps us move toward our Goals and what shows up as constraints from reaching them.

Shipping quality software, fast

What does it take to focus on the prize and ship valuable and high quality software as fast as possible?

Without writing out another agile manifesto, here are some fundamentals (in “Faw’s Laws” format, and not necessarily in order):

  1. Coordinate, communicate and collaborate with your teammates and customers recurrently
  2. K.I.S.S. – “steer the ship” in small increments with your eyes on your end goals (shipping quality software, fast… remember?)
  3. Give your team and your customer plenty of feedback on your progress in as low-cost a way as you can
  4. Don’t pretend to know everything up front, or that things won’t change along the way
  5. Team trust – you have to know your teammates have your back, and you’ve got theirs
  6. Avoid, minimize and/or eliminate rework – let’s not waste the precious hours of our lives
  7. Automate tedious tasks (testing, build, etc.) to remove manual errors/omissions and cut overhead time
  8. If you want to reduce the need for brittle documentation, draw pictures and don’t forget to write logs
  9. “Those who say it is impossible should get out of the way of those doing it” – a favorite quote (not sure where it originated)
  10. Umm… and a pet peeve – be suspicious of null pointers and poor exception handling (I couldn’t leave these out)

My primary concern in writing these out is to maximize throughput while simultaneously minimizing “inventory” and “operating expense”. Again, we may talk about those two later on. Whichever development method you embrace, your tactics are likely to be oriented around achieving  more fundamental interim goals like these.

What others would you add to the list? How would you frame your objectives differently?