This second post in the Making Software Quality Visible series describes the beginning of my personal journey with software quality and automated testing.
I’ll update the full Making Software Quality Visible presentation as this series progresses. Feel free to send me feedback, thoughts, or questions via email or by posting them on the LinkedIn announcement corresponding to this post.
Picking up right after the previous post, Starting the Making Software Quality Visible blog series…
How it started…
There’s a big story behind how I arrived at these conclusions, and what I’ve learned about leading others to embrace them as well. It begins with the fact that programming wasn’t my original plan.
From the beginning, I’ve always loved music—so much so that my first attempt at college led me to Berklee College of Music in Boston. It wasn’t just the beauty of the music that was attractive, or what I then believed to be the glamorous lifestyle. It was the idea of being part of a band, part of a team, pushing boundaries and achieving great things together.
Unfortunately—or fortunately?—the rock star plan didn’t work out, and I fell back on my second love: programming.1
Northrop Grumman Mission Systems
Navigation for US Coast Guard vessels and US Navy submarines
My first job as a software developer was working on US Coast Guard and US Navy nuclear submarine navigation systems at Northrop Grumman Mission Systems.
My “Library”
My colleagues at the time poked fun at me for carrying my “library” of programming and algorithms books with me everyday. I was learning what good code looked like by being able to see and understand what it looked like.
Then, my team went through a “death march.”
Death March
Experiencing “suffering” in software
A “death march” is a crushing experience of working insane hours to deliver on impossible requirements by an impossible deadline. This usually involves changing a fragile, untested code base that barely works to begin with, which was the case for our project. But somehow, we did it. We met the spec by the deadline, and then were given the freedom to do whatever we could to make the damn thing faster.
During this period of relative calm, I began to learn a few things.
Expectations: Requirements + Assumptions
The reason why poor quality can lead to suffering
I began to learn the relationship between code quality and expectations, which is the sum of requirements and unwritten assumptions.2
Requirement | Enumerate chart features |
---|---|
Assumption | In memory size == on disk size |
Reality | 21 bytes on disk, 24 in memory |
Outcome | File size/24 == 12.5% data loss |
Impact | Caught before shipping! |
Requirement: One day our product owner sent us some code to enumerate nautical chart features from a file.
Assumption: The code assumed each record was the same size in memory as it was on disk.
Reality: However, the records were 21 bytes on disk, but the in memory structs were 24 bytes, thanks to byte padding.
Outcome: As a result, this code ignored one eighth of the chart features in the file. The product owner’s lack of complete understanding led to overconfidence that masked a potentially severe quality issue.
Impact: Fortunately I caught this before it shipped to any nuclear submarines.
Not long after that…
Discovering unit testing—by accident
Curiosity and serendipity, not training or culture
I discovered unit testing, completely by accident, from Koss and Langr’s C/C++ Users Journal article “Test Driven Development in C/C++”.
With my library and my newfound testing practice in hand, I rewrote an entire subsystem from the ground up. I’d apply a design principle, or an algorithm, and exercise it with focused, fast, thorough tests every step of the way, rather than waiting for system integration. I could immediately see the results to validate that each part worked as planned, and spend more time developing than debugging.
In the end, my new subsystem improved performance by a factor of 18x and saved the project. And when a bug or two cropped up, I could investigate, reproduce, fix, validate, and ship a new version the same day—not the next week, or the next month.
I wish I could say I was well trained or mentored, or that the culture encouraged my development. The truth is I was entirely self-motivated. Although my teammates recognized my abilities, they never adopted my practices, despite their obvious impact. I couldn’t figure out why.
So I put my house on the market, quit my job, and met a woman on an online dating site whose referral led to me joining Google in 2005. In that order.
Coming up next
The next post will give a super fast overview of my experiences helping to drive widespread adoption of automated testing at Google.
Footnotes
-
This was after getting a theatre degree from Christopher Newport University and quitting my band, The Prime Ministers of Audiophonics. I ended up working in the shipping department of Optima Graphics, just outside of St. Louis, before going back to CNU for computer science. After leading a successful protest to save the Computer Science and Environmental Science grad programs, I finished my CS degree, and that was that. ↩
-
I first defined “expectations” in terms of “requirements” and “assumptions” in my talk “Automated Testing—Why Bother?” ↩