Test-Driven Career Development
I started this blog a year ago with the intention of sharing some of my work. I think it has gone roughly according to plan. I'm satisfied that I averaged an essay a month — that feels about right for me. Looking back, there are things I would change, but for the most part, I'm pleased with my writing and I'm glad I took the time to capture and refine these ideas.
As I reflect on the content, almost all of what I've written over the past year has been about software testing. For someone reading this blog, it would be easy to conclude that I am a software tester and that software testing is my passion. This is a perception I've also encountered a number of times at work. I've had comments along the lines of "you are very good at testing and you seem to be really passionate about testing, why don't you make it the focus of your career?"
I do really enjoy testing software. I am passionate about it. I want it to be a large part of my day-to-day work. But I do not want it to be the focus of my work. I'm an engineer. I enjoy designing and building new things, understanding complex systems, and making existing systems better. I consider myself a software developer first and foremost. I don't enjoy testing for testing's sake. I enjoy testing when it lets me understand something better, when it clearly defines a goal, when it leads to a better design, when it feeds my creativity, or when it acts as a safety net so that I can aggressively refactor things to make them bigger, better, or faster.
Testing appeals to my personality. I'm naturally skeptical. I believe error lurks in what appears true and what appears false. I try my best to be accurate, to get things straight, and to avoid errors in reasoning. I thought I would reflect on the impact software testing has had on my career development and, in many ways, how it has shaped my career.
Software Testing as Career Development
The first influence testing has had on my career development is one of continuous learning. Testing is a way of experimenting — changing something about a system and observing what happens — validating my assumptions, or leading to surprises. Testing, more often than not, is great for discovering what I don't know. Testing helps me develop my intuition for the complex interactions of software systems. Testing also makes me comfortable modifying and evolving systems, rather than viewing them as static or fragile entities that cannot be changed. The more discipline I have developed in writing tests, the better my work has become in terms of usability, flexibility, maintainability, extensibility, and reliability.
As a development lead, I find testing is a great way to fuel creativity and define product direction. On one project I was a part of, testing defined the entire project. It informed us what to build. I was working on a server product and we wanted to enter a new market. In order to do that, we needed to scale the server in almost all dimensions (e.g., record count, input transaction rate, the number of publish/subscribe clients, etc.) by at least an order of magnitude. We didn't just need incremental performance and scalability, we needed a game changer. As the performance and scalability lead for this project, I started by writing a bunch of tests that carefully measured the performance and scalability for each dimension of interest. These tests quickly showed unexpected and often non-intuitive results. They became the basis for finding and improving all of the bottlenecks. The tests allowed me to study the complex dynamics of the system under test in terms of memory, concurrency, IO, etc. and they fed my creativity. These tests also became the means of evaluating various approaches and measuring whether or not we met our goals. In the end, we were able to meet all of the performance and scalability targets for the project. And, in some cases, we even exceeded them by an order of magnitude. We were able to do this without changing the architecture of the product, meaning that the system was just bigger and faster, without changing how customers used it, how it was documented, or how it was supported. This was extremely rewarding. We also learned that many of the bottlenecks were not only important in terms of scaling the server to enter the new market, but were also subtly impacting existing systems. These tests remain useful today as regression tests.
Lastly, I like how good test automation allows me to evolve a system rapidly while at the same time delivering very high quality software. Another project I worked on was the development of a cloud service. This was the first cloud service my employer had developed, so there was very little experience to draw on. Extensive build, test, and deployment automation (some of which I've written about previously) enabled us to build a very reliable product and quickly get new features into the production environment. Twice, we significantly changed the architecture of the service (once in terms of locking/concurrency and the other in terms of the security model) and both times we were able to complete this work quickly and with the confidence to push it to the production environment without regressions that would impact customers or operations. I think the investment in so much test automation was perceived as anal, or perhaps even a waste of time. Thinking along the lines of "we want to be agile, so we can't tie our hands with all these tests". But, in the end, it was the automation that enabled us to be so aggressive and deliver such high quality work. I think it also led us to a much better design, something which could not be achieved by adding acceptance tests after the fact. This was the most rewarding project I've ever worked on. The feeling of having the freedom to radically change the architecture and quickly put the product back together again was an amazing one. These initial investments gave us a huge velocity in the end.
So, as I reflect on what I've written over the past year, yes, a lot of it was about testing. I dedicate a lot of time to the craft of software testing. But don't let me mislead you. What I value is not a religious devotion to test driven development on the micro level of write a test that fails, then implement or refactor the program to make the test pass. What I embrace is test driven development on the macro level, using it to learn new things, inform development decision, set objectives and be able to measure against them, and modify things aggressively without fear of regressions. Embrace testing. Let it feed your creativity and enrich your career path as a developer.