Are there benefits of reading code without being able to write code?

Standard

At the August London Tester Gathering, Alan Parkinson of Hindsight Software [1], gave a great talk on how “Pull Requests can be a tester’s best friend”. During this talk Alan mentioned the benefits of testers “reading code”. This statement seemed to spark some disagreement among those attending. In my experience, I agree with Alan, as a tester I find reading code a valuable source of information to support my testing, after all discovering information is one of our main objectives:

“…your ultimate goal in exploring is to discover information of interest and value to your stakeholders(the people on your team and any others who have vested interest in the information you discover.)”
Elisabeth Hendrickson – Explore It!

The activity of reading code can itself be fruitful to a tester as you may find bugs in the code and unexpected behavior without even executing the code. In my experience the clear benefit of reading code is that it provides information that can be used to drive a conversation about the product and can feed into exploratory testing charters.

The obvious question when talking about reading code is “Why would anyone choose to ‘just’ read code and not write it”

At this point it probably helps for me to define what I mean by “read”. When I refer to reading code I’m not simply talking about reading the words on the page, out of any sort of context these would just be letters, numbers and symbols. When I talk about reading code I’m talking about the following:

Looking for patterns in the code – To begin to understand patterns within code you are probably going to need to understand some of the basic elements of computer programs. Things such as If statements, loops, lists, operators, different types of inputs/outputs(Strings, Integers, Booleans). This basic knowledge can be picked up quite quickly and it doesn’t mean you need to be able to write them. A good example would be if your product provides applications based upon age. For example, any applicants over 30 are successful and under unsuccessful. The code implemented could be:

If (age => 30)
{
applicationSuccess = true;
}
else (age <30)
{
applicationSuccess = false;
}

Based upon reading this code within the context I’ve provided, let me guess, you have some questions, you can see some errors, it’s intentional. In this very simple case you have “read” code within a context, you have used this information and now have some questions to go and explore.

Readability of the code – A big success factor of reading coding is for it to actually be readable in the first place.

“…clean code should read like well-written prose. Think back on a really good book that you’ve read. Remember how the words disappeared to be replaced by images! It was like watching a movie, wasn’t it? Better! You saw the characters, you heard the sounds, you experienced the pathos and the humor. Reading clean code will never be quite like reading Lord of the Rings. Still, the liter-ary metaphor is not a bad one. Like a good novel, clean code should clearly expose the ten-sions in the problem to be solved.”
Robert C. Martin(Uncle Bob) – A handbook for Agile Software Craftsmanship

Ensuring the readability of the code means that when another member of the team comes to pick up the code, maybe later on for a refactor, the code should be easier to read and understand. Good commenting throughout the code can aid the team but it should be noted, there’s nothing better than a conversation, but as teams evolve the original writer of the software may not always be around.

Reading the files that have changed? – Another element of reading code is reviewing what files have actually changed. A good commit discipline that ensures linking to a work item, such as a User Story[2] and a concise summary of the changes can also help when it comes to reading any changes. Looking at the files in the context of the commit can immediately throw up questions if files have changed that you were not expecting. I’ve seen some examples of developers accidentally committing incorrect files. Use a commit monitor tool that runs in the system tray and alerts you when any files are updated[3]. You can decide if you want to go and explore any of these files, read these changes and if required, take further action (e.g go and speak to someone)

Comparing the code changes – Finally, another good approach to reading code is to do comparisons. Most Source Code Management tools allow you to compare changes to files[4]. Based upon the context of the change, the differences can often reveal interesting information. If you keep changes small you should be able to review the changes easily. This can throw up some questions and also provide low level information about what has changed in the application. This can help drive your exploratory test charters.

At this point i should say that locking yourself away in a room to read a whole bunch of code is probably not going to be very interesting. Reading the code together, with the author, is likely to more engaging and beneficial. Pairing up, as discussed in my previous blog post, is probably the way to go.

There are countless benefits to reading before you can write. Don’t forget though, there are even more benefits from testing before there is even code to read.

[1] Hindsight Softwarehttp://hindsightsoftware.com/
[2] JIRA Pluginhttps://confluence.atlassian.com/display/JIRA/Integrating+JIRA+with+Subversion
[3] Commit Monitor Toolhttp://stefanstools.sourceforge.net/CommitMonitor.html
[4] SVN Diff Toolhttp://svnbook.red-bean.com/en/1.7/svn.ref.svn.c.diff.html

Advertisements

Practical tips for pairing with a developer to test

Standard

Pairing is seen to be a popular way of working with software. The two common types of pairing are “pair programming” and “pair testing”. In both examples I think of the words “programming” and “testing” to refer to activities rather than roles. This means anyone can take part in these pairs. In my experience pair testing works well with two testers but also with a tester and a developer.

James Bach and Cem Kaner explain pair testing as:

“Pair testing is different from many other kinds of pair work because testing is an *idea generation activity* rather than a plan implementation activity. Testing is a heuristic search of an open-ended and multi- dimensional space. Pairing has the effect of forcing each tester to explain ideas and react to ideas. When one tester must phrase his thoughts to another tester, that simple process of phrasing seems to bring the ideas into better focus and naturally triggers more ideas. If faithfully performed, we believe this will result in more and better ideas that inform the tests.”[1]

Pairing with a developer to test is a great way to learn about a product, resolve bugs quickly, generate test ideas and a great opportunity to increase testability.

When originally working in cross functional agile teams I found it difficult to identify how to approach pairing with developers. All too often, developers and testers worked in silos waiting for the code to be moved to the “Ready for Testing” column on the Task board[2]. On the occasions i attempted to work more closely with developers it was hard to keep the conversation going more than a few minutes.

One “tool” I’ve found incredibly useful to aid pair testing sessions with developers is the debugger built into most development IDE’s such as Visual Studio[3] or Eclipse[4].

When coding a feature developers will use the debug capability to do just that, debug their code to check its doing what they expect and track any exceptions that may occur.

When it comes to pair testing with a developer our context will be slightly different. We are less concerned with “debugging” the code and more concerned with using the “debugger” as a tool to support testing. It is a great way to observe and control the application during testing.

The benefit of using this tool is that it facilitates the discussion between the developer and the tester. Ask the developer to “step through the code” using the debugger and explain as he goes. Don’t worry if you can’t code, the objective here, as I said earlier, is not to debug the code but to test. As the developer is talking through the code, ask questions, observe patterns within the code, and listen carefully to what he says and how he says it. As the debugger allows you to control the code it’s great for those moments when you ask the question “What If?”, “Can you show me?”, “Hold on a second.” It means as a pair you can explore those questions easily with complete control over the code going back and forth as you please. Don’t expect answers to all your questions and don’t dwell too much on a single point. Take diligent notes and return to these later in the session or in a following pair session.

Having the ability to stop at points in the code also enables the developer to point out important parts of the code. For example parts that directly relate to the Acceptance Criteria of a Story such as a calculation algorithm.

To support this conversation ask about Unit Tests that have been written to check the code. Ask the developer to step into the unit tests and explain what has and also importantly hasn’t been unit tested.

The joy of pairing also means a quick fix and retest process. It’s possible for simple bugs to be fixed there and then with more complex bugs can be recorded ready for the fix to be explored in your next pair session. Getting familiar with the debug process enables you to also debug through the code should you find any bugs. For many issues exceptions will be thrown by the application so you can point these out to the developer should you find an issue. If your comfortable with code, you could even code up a fix and review it with your developer.

Another good output from this pairing session is ideas for exploratory testing sessions. You can ask the developer areas he’s perhaps uncomfortable with and in many cases I’ve found developers more than forthcoming with that information. During your pairing its natural for there to be some areas your not entirely comfortable with and the gut instinct will kick in. As the story matures towards “Done” you may find your pairing sessions move away from the debug tool and become more exploratory in nature.

It’s important to pair throughout the story, not just at the end. Find a balance that works for your team. The developers within my current team are good because they will shout once when they need me and on the flip side are open to me approaching if I want to pair up. Alternative approaches are to schedule calendar reminders at the start/end of each day or after lunch, this might support testers in large development teams. Pairing frequently means that you will gradually take bites of the story rather than being overwhelmed at the end. Bringing questions or bugs you’ve observed in your own testing also helps kick start the next pairing session. Getting access to the application code and being able to run it locally will help you prepare for your next session. It will also help you get more familiar with the capabilities of the development IDE.

Another good benefit of pairing is testability. Explaining how you’d like to control and observe the application allows you to directly influence the design of the code. Maybe you’d like the logging to be improved, maybe a different kind of variable to be used that’s better for automated checks, or maybe you need a method to tear down data. These are examples of Intrinsic Testability and James Bach explains there are other forms of Testability[5]. In my experience many of these are emphasised through pairing:

Intrinsic Testability – “If we hadn’t agreed during our pairing to put in extra logging we may never have noticed it”

Project Related Testability – “Having the developer explain areas he wasn’t too comfortable with and couldn’t Unit Test helped us really focus our exploratory testing charters in those areas.”

Value Related Testability -“Through our pairing we have built a strong rapport and we are comfortable asking each other challenging questions or constructive feedback”

Subjective Testability – “Now I know how to run the application locally I can debug through the code and provide more technical information about where the code might be going wrong. I sometimes even feel comfortable coding a fix.”

So in summary, pairing with a developer is a really effective way of testing. Use the tools available such as the debugger as a way to facilitate the conversation between yourself and the developer. As your relationship grows you’ll find your sessions become more efficient allowing for more time to be spent on the complex and complicated areas.

[1] Exploratory Testing in Pairs – http://www.kaner.com/pdfs/exptest.pdf

[2] I’ve found that when teams have “testing” columns on task boards it encourages developers and testers to work in silos. I personally prefer To Do – In Progress – Done.

[3] Debugging in Visual Studio – http://msdn.microsoft.com/en-gb/library/sc65sadd.aspx

[4] Debugging in Eclipse – http://www.eclipse.org/jetty/documentation/current/debugging-with-eclipse.html

[5] Heuristics of Software Testability – http://www.satisfice.com/tools/testable.pdf