About This Blog

Hi, I'm Ben Pryor. This blog contains my thoughts about general software engineering topics, and occasionally specifics that I find interesting. If you see something here that sparks your interest, please feel free to comment on a post or send me an email at ben at benpryor.com.

23 January 2007 - 17:08Tips for Pair Programming

I’ll start off by saying I am a big proponent of pair programming. It’s a very effective programming style when used in moderation. I read stories about some places that pair all of the time for everything - while I’ve never worked in that kind of environment, I can’t imagine it would be too pleasant. There are too many programming activities that involve “think time” in which you’re not talking, not typing, not reading, but simply processing. Depending on the kind of work you’re doing, this think time may be a big or small part of your day, but either way it’s an important part.

However, pair programming is great for some tasks. Lately I’ve been pairing with a colleague to hammer out the finishing touches on a feature for an upcoming release, and pairing to do this is working really well. Along the way, I’ve done a few small things to make the overall pair programming experience as effective as possible.

Environment
If you’re going to be pair programming for any length of time (more than an hour or two), getting the environmental factors right is crucial. Pairing in a noisy environment isn’t as effective as pairing with fewer distractions. At the same time, realize that pairing creates a fair amount of extra noise in the environment that wouldn’t otherwise be there (especially if you work in an office environment), so be respectful of your non-pairing coworkers.

A clean and open work space is a must. Both programmers have to feel comfortable - if your counterpart has to dig through last week’s sandwich wrappers and who knows what else in order to find a place to work, you’re probably not going to have an effective pairing experience. If you will be doing some extended pairing, spend some time before you start cleaning up your work environment. By reducing the amount of clutter and having clean work surfaces, your pair will feel much more comfortable and willing to invest in the effort.

Along these same lines, consider closing programs which pop up intrusive notifications for the duration of the pairing session. This includes things like mail readers and feed readers that have the habit of popping up temporary windows to alert you of new items. This will only distract from the pairing session and your pairing partner probably doesn’t care to see the notifications anyway. If you’re worried about missing important mail, just take a 10 minute break every couple of hours and check for any urgent messages then.

Another point is that you need lots of collaboration material. At a minimum this means a large, clean whiteboard with plenty of markers and an eraser. It’s surprising to notice the psychological effect of a whiteboard that’s been freshly cleaned with whiteboard cleaner compared to one that’s dirty and lightly erased with a felt eraser. Also good to have on hand is plenty of pads of paper and pens for jotting down quick notes and diagrams.

Input Devices
Ideally pair programming doesn’t work like drivers ed. Each participant should be just that - a participant and not an observer. It’s great that you can show off your mad programming skillz to your pairing partner, but that isn’t really the point of the exercise. The ideal pairing setup involves dual everything - 2 keyboards, 2 mice, and 2 monitors. In my case I had only a single monitor handy but there are plenty of extra mice and keyboards laying around, so I plugged in a second set of input devices and we were off to the races.

The ability to have both pairs able to code without having to play chair tetris or keyboard shuffle saves a lot of time. Often this means one of the programmers can pick up in the middle of a block of code where the other left off, and you don’t have to context switch at all. This also means that you’re not bumping elbows when trying to scroll around through a class (personal space is important to many programmers :)).

If you are going to use only a single monitor, be sure to position the monitor so that it can be easily seen by both. Often this is a different position from what is optimal for a single programmer so don’t be afraid to slide the monitor around when starting the pairing session to find the best spot.

Of course it goes without saying that you need to have two comfortable chairs and plenty of space to sit in. If you want to go all out there is always the PairOn. :)

Fonts
A prerequisite for this kind of extended pairing session is to increase the font size in the tools you’ll be using together. This is less of an issue if you’re using multiple monitors, but it’s still important to consider it. That 10 point font you use with your 21″ 1600×1200 monitor doesn’t look nearly as good when your face isn’t 4 inches from the screen. In Eclipse, I set the text font to be Consolas at 14pt, which works great for pairing off of a single monitor. Consolas looks great on LCD monitors with cleartype enabled, and if you are legally allowed to install it on your machine I can’t recommend it enough. Of course, the downside of larger fonts is that you can’t see as much code at a time, but it means that you don’t get eyestrain or headaches and both programmers have a good view.

ZoomIt
Finally, I highly recommend installing the ZoomIt utility from Sysinternals on the computer before beginning the pairing session. This utility was written to help aid presentations, but it’s perfect for pair programming.

ZoomIt has two extremely useful features for pairing. First, with the press of a hotkey, you can use the mouse wheel to zoom in on any portion of the screen. Even if you’ve bumped up the font sizes as I suggested above, there will probably still be times that a little zooming is needed to narrow in on something. If you or your pairing partner need to often lean closer to the monitor to try to read something, ZoomIt will be a huge help.

Secondly, ZoomIt has a great annotation feature that allows you to draw on the screen. This can be great for pairing - instead of smudging up the screen every time you need to point out something, simply press a hotkey and use the annotation feature instead. This is a really underrated feature for pairing - how many times have you wanted to point at a section of the code or highlight a particular block? Again, this feature is all hotkey driven and the ZoomIt utility overall is very well done.

Conclusion
Keep in mind that pair programming can be mentally draining. Often a 6 hour work day pairing is easily the equivalent of an 8 hour work day alone, especially if you don’t pair often. When done right, you can temporarily boost your effective output, but when done wrong, it can be an excuse to slack. Also I’ve found that during pairing you will often discover tasks that one or the other of you need to do, but doing those tasks as a pair would be a waste of time. The best thing to do is to keep a list of “action items” that are related to the task at hand but will be completed outside of a pairing session. If you do this, be sure to put appropriate TODOs in the code and keep your parter informed about the progress of your action items.

No Comments | Tags: Uncategorized

17 January 2007 - 16:37If you need ShouldNeverHappenException, you’re calling a bad API

Over on Artima, Bill Venners posted a question about exception handling. When an API declares that an exception could be thrown, it is saying that something could go wrong. This is, of course, a conditional declaration (if an exception was thrown every time, the API would not be very useful). As it happens, often the API makes a guarantee that under certain conditions, an exception will never be thrown. As a client of the API, how do you handle the case when you’re calling in and are guaranteed to be in a case where an exception will not happen?

Here’s (roughly) the example from the linked article:

// Processes the given input string using the given character encoding. 
// If the given encoding is not supported, throws an UnsupportedEncodingException.
// The “UTF-8″ encoding is guaranteed to always be supported.

public String doSomething(String input, String encoding) throws UnsupportedEncodingException
{
   …
}

Java’s checked exceptions make this situation worse. In other languages that support exceptions but don’t have the concept of compile-time checking of exception handling, developers usually ignore this case. And after all, why not? If you are calling an API in such a way that an exception is guaranteed to not be thrown, then there is no reason to put in exception handling code. Unless, of course, you are programming in Java and the exception is checked, in which case you must handle the exception whether you want to or not, even when you are guaranteed by the API that your handling code will never get called.

The usual thing to do here is to simply handle the “impossible” exception by rethrowing it wrapped in an unchecked exception, like RuntimeException. This looks something like:

try
{
   doSomething(”an input value”, “UTF-8″);
}
catch (UnsupportedEncodingException shouldNeverHappen)
{
   // according to the API docs, “UTF-8″ is always supported
   throw new RuntimeException(shouldNeverHappen);
}

But I’d like to look at this from the point of view of the API producer and not the API consumer. The fact that the API consumer has this problem about how to handle an “impossible” exception indicates an API bug. The fix is to split the API into multiple methods that have different guarantees, adding the following method in addition to the method above:

// Processes the given input string using the “UTF-8″ character encoding.
// To process with another character encoding, see doSomething(String input, String encoding).

public String doSomethingUtf8(String input)
{
   …
}

Since the API is smart enough to guarantee a special case (no UnsupportedEncodingException) for UTF-8 in the API documentation, why not make that special case explicit? As it often happens (eg java.net.URLEncoder.encode) the special non-exception case is the normal case. Why not optimize for the normal case?

There are many ways to do this. If there are multiple “good” values that will result in no exception being thrown, create a version of the API that takes an enumerated value (and doesn’t throw) and one that takes a simple data type like String (and throws).

Of course, if the API didn’t use checked exceptions, this would all be a moot point. I rarely throw checked exceptions when writing new code, and encourage others to do the same. Checked exceptions are useful in certain situations, and I enjoy having them in the Java tool chest. However, they’re vastly overused and in most cases APIs that throw checked exceptions should be converted to throw unchecked. I’ve touched on this point before, and there’s plenty of opinion in agreement (and disagreement :)) out there on the web.

BTW, in the example code above, you could make an argument that the exception should really be an IllegalArgumentException (which is unchecked). UnsupportedEncodingException extends IOException, which is a bit strange to throw as an argument validation exception when IllegalArgumentException exists for that purpose.

No Comments | Tags: Uncategorized

16 January 2007 - 9:25State-based vs. Interaction-based Unit Testing

State-based and interaction-based unit tests differ greatly in style, although they each have the same end goal, which is verification of a unit of code. The ultimate difference between the two is what attributes of a unit of code are tested in order to consider whether or not the unit of code is correct. It’s important for a software developer to know both styles and to understand the differences between the two.

State-based testing
A state-based unit test is written in a style of unit testing that many software developers would be familiar with. In fact it wouldn’t be far off to call this “traditional” unit testing. In a state-based test, the first step is to initialize the unit under test. This initialization may include creation of test data and graphs of supporting objects necessary to exercise the unit under test. The test then exercises the unit by calling methods on it. When the test has finished exercising the unit, assuming no errors have yet been raised, the test then proceeds to verify expected state of the unit. In JUnit parlance, this verification is usually done using the assert*() methods. No matter what testing harness is used, this verification takes the form of testing state and raising errors if the actual state differs from expected state.

A little more about those supporting objects alluded to in the previous paragraph. One of the challenges of unit testing is to sufficiently decouple the multiple units of code that make up an application so that each unit can be tested individually. Otherwise, you end up with a “unit” test that’s really more like an integration test. Often this decoupling can be hard. A variety of techniques have been developed to help in this decoupling, but the most important technique is to program to interfaces instead of concrete classes. There should be an interface at all of the coupling boundaries of your unit of code. If this single condition is met, writing effective unit tests will become much easier. Often the supporting objects used by a test harness to properly exercise a unit are stubs. A stub is a trivial implementation of an interface that exists for the purpose of collecting state during a unit test.

Stubs are most often written by hand, although they don’t have to be. Usually you will end up creating a graph of stubs and trivial real objects that parallels the graph of real objects (both complex and trivial) present when the application is running. As the unit under test uses the stubs, they stubs collect state that can be verified at the end of the test. We’ll come back to stubs later on when we talk about mock objects. For now, keep in mind that stubs are often created by hand and exist to collect state for verification purposes.

How a state-based unit test works shouldn’t be a surprise to anyone who’s ever written a unit test. One of the advantages of this style of unit testing is its simplicity. It doesn’t take long to teach someone how to write tests in this style, and the overall behavior of the test is intuitive. It kind of feels like the way we might test something outside of the realm of software development.

The important thing to note is what criteria the state-based unit test is considering about the unit under test. It is, not surprisingly, all about state. If the unit under test reaches a certain state, it is considered correct. The state-based unit test doesn’t really care how the unit got to that state, but only that it is there at the end. The phrase “the end justifies the means” is apt here. The means (behavior of the unit) doesn’t matter nearly as much as the end (state). In fact, the only thing a state-based unit test verifies about the means is that the behavior of the unit didn’t include raising any errors during the test.

Are state-based unit tests effective? Absolutely. The best evidence of which is that most unit tests today are being written in this style. The end state of a unit is in many cases very significant from a verification standpoint. The end user of an application certainly cares more about state than behavior (here, behavior being that of internal objects and not external behavior of the application itself). When you’re using an online banking application the bottom line is that you want your balance to be the correct one.

Interaction-based testing
An interaction-based unit test is different. The easiest way to explain would be to say that an interaction-based test verifies the behavior of a unit instead of verifying the unit’s end state. From the point of view of an interaction-based test, the correctness of a unit is based on how it interacts with its neighbors, and not with internal state of the unit.

An interaction-based unit test first initializes the unit under test. This is done by creating “fake” stand-ins for all of the unit’s immediate neighbors. A neighbor is any object that the unit under test passes messages to (calls methods on). These stand-ins are called mock objects, and are usually created by a test framework library. When the initialization is complete, the only “real” thing in the graph of objects is the unit under test. Everything that the unit is hooked up to is a mock object - capable of receiving the same messages as the real object.

There is then a second step to the initialization of an interaction-based unit tests. After all of the mock objects have been initialized, expectations are set on the mocks. This is exactly what it sounds like - the test code programs the mocks and tells them what messages to expect from the unit under test. This can include many things such as what order to expect messages in, what the parameters to method calls should look like, and often how the mock should respond to these messages.

Contrast mocks and stubs. I know that in many places these two terms are used synonymously, but they are really very different from each other. A mock is often generated by a test framework library, while a stub is often created by hand. The internal state of a mock doesn’t matter at all - only the expectations it has about the messages it receives. A stub exists to collect state. Stubs are often used in conjunction with “real” objects. For instance, if an existing real object is very simple and lightly coupled to the rest of the code base, it is often brought in by testing code as a supporting object to the unit under test. A stub is normally only created when the real object can’t be used in a test harness for various reasons (coupling, external dependencies, etc). Mocks are used exclusively in an interaction-based unit test - all of the unit’s immediate neighbors are mocks, even when the real object is trivial.

The final stage in an interaction-based unit test exercises the unit. During this phase, the test code is invoking methods on the unit under test, which itself is interacting with the mock objects. A test error will be raised by the mocks if expectations are not met. An expectation can fail to be met for a variety of reasons, including if methods are called in the wrong order, if parameters have unexpected values, if the wrong methods are called, or if the right methods are not called. At the end of this phase the interaction-based unit test completes. There is no state-checking of the unit under test. If all expectations of the mock objects have been met, then the unit has been verified from the point of view of the test.

Are interaction-based unit tests effective? To really answer that question you have to look at the motivation for this style of testing. Object-oriented development might have been called behavior-driven development if it had been invented in this decade. (I know that there is an existing methodology termed behavior-driven development, but it is really based on OO being done right if you look closely). What is a more useful measure of the correctness of a unit - its behavior or its state? A OO purist would hopefully answer that behavior is key while state should be internal and encapsulated. An interaction-based unit test verifies behavior, while a state-based unit test verifies state.

Interaction-based unit tests are great for completely isolating the unit under test, and thereby are very true unit tests. A properly done interaction-based test cannot be testing anything other than the unit, while it is not hard for a state-based test to rely on side effects and be a little sloppy about boundaries between the unit under test and other units in the application. Interaction-based testing is most useful when applied uniformly throughout a code base. The objects that you create mocks for in a interaction-based test will themselves need interaction-based tests in order to feel confident about the code base as a whole.

Deciding which style to use
One of the premises of this article is that it’s important for today’s software developer to understand the large differences between state-based and interaction-based unit testing. However, for any of this to be of practical use, you will eventually have to make decisions about which style to use when writing a test.

I find that interaction-based testing feels a little unnatural. You can certainly make the argument that an interaction-based unit test is more tightly coupled to the implementation of a unit than a state-based unit test is (the counter-argument is that this is a good thing, not a bad thing). I’ve also noticed that interaction-based unit tests tend to have a lot more plumbing code that state-based tests. Coming back to a state-based unit test after a few months is usually easy - coming back to an interaction-based test often involves lots of inspection to get back up to speed. In other words, I posit that interaction-based unit tests have a higher maintainability cost than state-based tests. I think a lot of this is a reflection of the current state of languages and libraries in which interaction-based tests are written. This is still a fairly new testing style, and over time much improvement will be made in the libraries and frameworks that support it.

Finally, I’d like to suggest that different kinds of code benefit differently from each style. Some code is very stateful, and is best tested with a state-based test. Other code is more stateless and can be fully tested only with an interaction-based style. Perhaps the right question isn’t about knowing which style is better in an absolute sense, but more about being able to recognize which style will be most effective for a particular piece of code.

Further reading
Martin Fowler: Mocks Aren’t Stubs
If interaction-based unit testing is new to you, start by reading this article. You’re likely also going to have to spend some time writing interaction-based tests against a code base you know well before the differences between the two styles start to sink in. This is one of those cases where “armchair programming” isn’t going to help - you have to dive in and try it to fully appreciate the differences between the two styles.

Behavior-Driven Development (BDD)
Many of the motivations behind interaction-based testing come from an increasing focus on behavior and less on state. From the linked site: “It must be stressed that BDD is a rephrasing of existing good practice, it is not a radically new departure.”

Mock Roles, not Objects (PDF)
A paper written by the authors of JMock, a popular Java mock object library. The paper is short and very readable. I highly recommend it to anyone trying to understand the purpose of mock objects and how they differ from stubs and state-based testing.

State vs. Interaction Based Testing Example
A blog entry by Nat Pryce, one of the developers on the JMock project, that gives an example of a state-based and an interaction-based unit test for the same piece of code.

No Comments | Tags: Uncategorized