It’s vital to acknowledge from the outset that I am a reluctant programmer. I know how to program. I can piece together programs in a variety of languages, but it’s not something I consider myself accomplished at doing.
As a software tester, this is a common refrain that I have personally heard many times over the years. It’s so common that there is a stereotype that “people who can program, program. People who can’t program, test the code of programmers.” I disagree with that statement, but having compiled enough personal anecdotes over twenty years, I see why many people would have that view.
I see a traditional dividing line between a “programmer’s mindset” and a “tester’s mindset.” The easiest way that I can describe the difference is, to borrow from Ronald Gross’ book Peak Learning, a “stringer’s” vs. a “grouper’s” approach to tasks and challenges. If you are one who likes to work with small components, get them to work together, and “string” them into larger systems that interact, then you have a “programmer’s mindset.” If you look at things from different levels and “group” the items, see where there might be bad connections, and see if those bad connections can be exploited, then you exhibit a “tester’s mindset.” This is a gross oversimplification, but this idea helped me put into word why programming was a challenge for me. It was a "stringer" activity, and I was a "grouper."
I've used that as an excuse for years. I said to myself, "Well, it’s OK… I’m a tester. A grouper. I think differently. I don’t particularly like to code, so that’s OK, I’ll just be awesome elsewhere.” I’ve since come to realize that I was wrong. I'd been looking at this whole coding thing the wrong way, and not being completely honest with myself. The truth is, I was afraid. I was not quick with writing new code, I couldn’t solve the real problems that I had, and I was impatient, not willing to put in the real time necessary to get good at it. More to the point, it just wasn't all that much fun to do. I've since changed my mind on many of those points.
So, what in the world do I think I am doing writing an article to other software testers, telling them they shouldn’t fear code? Because we shouldn’t. It isn’t magic. It is systems thinking—science and logic—mixed with some rules that dictate where things go and when. In fact, I’m willing to bet that, if I were to sit down with a “non coding” software tester, I’d be able to show them that they write code all the time.
Every Tester Programs
If you have ever taken multiple commands and created a macro, or a shell script, and grouped commands into a single file and made it executable, you are programming. Yes, I realize that it doesn’t fit the common image we have when we talk about programming. We are not writing applications. We are not using some spiffy compiler and elaborate language. Still, if you are grouping commands together in one place to execute them, adding a variable here and there so that you can extend a shell script and make it a little more dynamic, or parsing the output of test logs to make a report, you are indeed programming. Even with software testing tools that are advertised as “no programming required”... if you are modifying files, changing values, switching the order, pointing different places… yes, you are indeed programming. All that’s different is the order of magnitude and the level of sophistication.
Programming Need Not be a Barrier
One of the bigger issues that I have come across as I’ve talked to software testers who lament their “inability to program” is the fact that they are mixing up their intentions. When a software tester says, “I am not a programmer,” what they are most likely saying is “I am someone who has not invested the time and energy into learning a variety of programming languages and techniques with the goal of making software for other people to use.”
That’s a fair statement, and yes, when put in that light, there are a lot of us software testers who are not “production grade shipping software level master programmers.”
That may seem a bit heavy, but work with me here. If I ride a snowboard, am I only allowed to call myself a snowboarder if I enter slopestyle events or halfpipe competitions? No, of course not. Then why should I feel like I have no right to call myself a “programmer” just because I haven’t shipped an application to market, or written some elaborate framework?
The more difficult issue is that, for many of us, programming is a smaller part of what we do. I much prefer exploration and open engagement with my own eyes to writing automated scripts, but the fact is, I can use my eyes a lot more frequently and effectively if I can identify the repetitive work that can be automated via programming. Often, it’s not that we can’t do the work, but that the work feels burdensome, onerous, or just plain irritating. When programming is boring and painful, we will not do it unless we absolutely have to. Therefore, I want to suggest that we try to find ways to make it less onerous, and make it, well, fun! Great, you say, how can we do that?
Ways Testers Can Get In Touch With Their Inner Programmer
Start Small, and Start Local
My first recommendation to anyone who wants to take a bigger step into programming is to “start with the shell.” If you use a PC, you have PowerShell. If you are using Mac or Linux, you have a number of shells to use (I do most of my shell scripting using bash). The point is, get in and see how you interact with the files and the data on your system that can inform your testing. Accessing files, looking for text patterns, moving things around or performing search and replace operations are things that the shell does exceptionally well.
Learning how to use the various command line options, and “batching commands” together is important. From there, many of the variable, conditional, looping and branching options that more dedicated programming languages use are available in the shell. The biggest benefit to shell programming is that there are many avenues that can be explored, and that a user can do something by many different means. It's kind of like a Choose Your Own Adventure book!
When in Rome, Do What Your Programmers Do
It’s not mandatory that we learn the same languages and use the same languages our programmers and engineers are using, but there are a number of benefits if we do. First, we have expertise that we can call on if we find ourselves stuck with questions. We can utilize work that has already been done and is stored in shared libraries. We can leverage existing infrastructure and take advantage of unit and integration tests that already exist to help inform additional tests that may be needed. All of this comes as a side benefit when we learn the languages our team actively uses.
There is a down side to this, too. If our testing infrastructure uses libraries from the development code to create our tests, we might get false positives, or we may have tests pass that really shouldn’t, because bugs in the underlying code mask errors. If you are just starting out, or are part of a small team, using the development infrastructure as a basis for your programming efforts makes sense. If you need to have a completely independent and isolated code base for testing purposes, then yes, having a different language and technology stack for testing might be a smart move.
Look For and Try to Solve Authentic Problems
Programming courses and books are optimized to teach syntax. They are not written to solve our unique problems. This is why simple examples in book often do not help us when we try to apply them to our own issues and circumstances. To this end I say, “Make every problem about you.” Ask yourself “how can I take this statement or idea and apply it to what I am working on right now?” Try to think about what you are learning and apply it immediately in your everyday work. If you have an output file that has a bunch of date and time stamps that you want to remove, start working with some ideas in your programming language of choice (or go old school and use sed or awk with regular expressions), but see what it takes to physically remove them reliably and get the output you want to keep. Not only will this be more applicable and usable, I’ll dare say it will make the learning process more enjoyable, too.
Carve Out Time Every Day For Consistent Practice
Most of us “less than expert” programmers can point to one reason; we have not put the time in on a consistent basis for it to become a regular habit. When I lift weights, I often stop training once I meet a goal, or began the activity I was training for. Much of the time, during long periods of down time, I would lose the gains I made. But I didn’t worry too much, because I could bring myself back to where I was quickly once I resumed my workouts. That phenomenon is caused by “muscle memory,” and to have muscle memory be a factor, you first have to build some muscle. Likewise, many languages I’ve used for various reasons over the years for programming (C, C++, Java, Tcl/Tk, Perl, Ruby, etc.) have a similar issue. If I do a bunch of work with one for a while, and then don’t touch it again for a few months, it’s almost like starting back at ground zero. But after a little time, I see the connections and my programming equivalent of “muscle memory” comes back.
Find a Partner and Work Together Where You Can
Donald Fagen of Steely Dan fame once said that “Walter [Becker, his songwriting partner] can’t start a song, and I can’t finish one. Therefore, we work great together!” I have a similar problem. I’m very much like Walter Becker when it comes to writing code. I can offer ideas and make additions to stuff that’s already underway, but put me in front of a blank text editor and say, “OK, write something” and we will be in for a struggle. Therefore, I try to take advantage of opportunities when I can work with people who can balance out my own abilities, or get some ideas so I can go in different directions based on where they have started. Two sets of eyes considering the same problem is always helpful. The debates and questions spawned from those interactions open up avenues neither of us alone would have considered. Also, this model allows both parties to swap the roles of programmer and tester, and communicate to both “mindsets.”
For Added Fun, Make It “Do Or Die”
I believe that situations that really put you in a pressure cooker, where failure is not an option, can be powerful drivers to making programming much more interesting. I had this experience recently by taking on the role of the build master and release owner for a week. When it was my turn, I came into work to find the build was red. The answer? Fix it! Even if I couldn’t do so myself, I was responsible to make sure that I found someone who could, whoever that person could be.
I had to get acquainted (and fast) with what was being checked in, which branches were being committed, were there any conflicts, why did tests fail, what could I isolate, and how could I get as specific as possible so I could either get the programmer most likely to be able to fix it, or do the work myself.
Sounds scary, huh? It was. It was also FUN! Knowing that I couldn’t slink into the shadows and hope someone else would take care of it, and that it was “do or die” time, I had to figure it out, communicate with the other programmers, and make the build green so we could push. It was an awesome experience. It showed how much I could learn in a short time, and how I could help the build and release process with the programming skills I already have. To use a snowboarding metaphor, I was standing on the lip of a twenty-foot cornice, deciding if I should drop in or not. In this situation, I was pushed off the lip. I had two choices… crash and burn, or stick the landing. I decided I was going to stick the landing.
My point with this article is to tell anyone out there who feels on the fence about their programming skills that you are not alone. I want to make sure you understand the foundation that you may already have in place. Most of us already program, we just don’t consider what we do, or how we do it, on par with what we consider “real programming.” If you are one who thinks that way, I’m asking you to stop it. Seriously. Learning how to program, and doing it in a meaningful way that will enhance your career immensely, has never been easier. No matter the language, platform, or problem, you will have to work at it… and regularly. The good news is, if you do, you will have a skill that can take you in may different directions—as a software tester and beyond.