This past Saturday I was fortunate to be one of the 60 people enrolled for the largest Code Retreat ever, Code Retreat Boulder, facilitated by Corey Haines and Chad Fowler, organized by Prakash Murthy. This was my first Code Retreat, though I’ve worked on teams practicing TDD, pair programming, and good design practices for more than ten years.
I was the only tester attending, and as I had feared, I was somewhat out of my depth. Nevertheless, I write automated tests, and I need to apply the same design basics to those as we do to production code. The past couple of years, I’ve tried to think of ways to help testers learn those principles, and written articles such as “An Intro to Test Design” in the Testing Planet. One goal of Code Retreat is stretching yourself, making ugly messes and not worrying about it even though our goal is perfection. I was definitely stretched way beyond my comfort zone!
Corey explained the basics we should practice:
- Tests pass – J.B. Rainsberger says this is “like breathing”.
- Don’t Repeat Yourself, keep code DRY
- Tests and code reveal intent – name things well
- Small – work in tiny increments.
The day was divided into 45-minute pairing sessions; we switched pairs each time. We wore name tags that indicated our programming language preferences. At the end of each session, we had to delete our code, stand up, and debrief for a few minutes about what we learned and what to try next. We also had a long lunch break (with delicious food!) The coding problem to solve was Conway’s Game of Life. As I dislike both math and puzzles, this scared me.
Mike Clark generously offered to pair with me in the first session. I’ve known Mike for ten years and he’s a TDD guru. We used RSpec and TextMate, both new to me (at work, we use test::unit with Ruby, and I use IntelliJ Idea). It was so natural for Mike to start writing a tiny test, then a tiny bit of code, which he put in the same file to start off – quite efficient. He had brought graph paper, which was handy for writing down examples of what a Game of Life grid would look like. We immediately set about creating and testing a board of cells. Corey came around to look at what we’d done, and commented that we should try to avoid numbers and X/Y coordinates. Hmmm. He mentioned encapsulation, which I understood to mean we don’t need to know about cells, only the board.
Apparently most everyone had started out creating a grid and using X/Y coordinates. For the second session, I paired with Erika Bricey, who works at Rally Software. We decided to follow Corey’s advice to start with the rules, to focus on the names for the methods, and whether the methods are doing too much. Corey mentioned that a class with plural name is a collection of other things. Erika and I had some good ideas on how to approach the problem, but for sure I couldn’t turn those into code, and Erika struggled too. Erika also used RSpec, but she worked in Eclipse.
Seeing our frustration, Corey and Chad suggested we less skilled persons find highly skilled pairs. So I waylaid Marty Haught, a test-obsessed programmer I’ve been wanting to talk to. He went along with my desire to focus on rules and on the names of things. For example, we started out with a module called “alive”, for cells that are alive. Later we needed to have dead cells, so we renamed that to “remain_alive” and the other module was called “dead_cell”. We wrote tests and code for most of the rules. We tried to follow Corey’s advice that “anytime you need to DO something, ASK another object”. For example, to find out if a cell is alive, ask “How many neighbors do I have?” and that will invoke an object that says “Here’s my number of neighbors, am I alive?”
Corey told us that if every time you have to make a decision, you ask someone(thing) else, you end up with no “if” statements. He challenged us to see how far we could go before we had to have a number. He noted that there are two parts to the rule: the hard-coded rule such as “Any live cell with fewer than two live neighbours dies” also states the spirit of the rule: “as if caused by under-population”. Aha! We should write our code in terms of under- and over-population instead of hard-coded boundaries.
My first pair after lunch, Anthony, used MacVim. I’m an old fan of Vim, but hadn’t seen MacVim. We talked about the fact that the grid is infinite, and decided to see if we could get information about the neighbors of any one cell, working with relative numbers. Anthony was pretty sharp at figuring out how to do this, and we made a lot of progress in the 45 minutes. Other pairs tried starting with the outside abstraction and working in.
I was getting tired and didn’t take as many notes in the afternoon – it was all I could do to keep up with what my pair was doing. I had low expectations with regard to my Ruby coding knowledge, but I learned how much I don’t know! For the last session, I was the kid who didn’t get picked for the softball team, I didn’t have a pair, so I observed Rob Park and his pair working in Java. I work on a Java team. It was interesting to see the immediate contrast of working in Ruby vs. Java for the same coding problems. Java looked much slower and more cumbersome to me.
We finished with a closing circle where each person stated what we learned, what surprised us, and what we’ll do differently back at work on Monday. Many of the participants were new to pairing and TDD. I’m not, but it reinforced the value I’ve gotten by learning through pairing with a programmer. I learn more about code design in an hour of pairing than from days of reading books. I plan to be more diligent in applying good design principles to automated test code – for example, pay more attention to using good names. I won’t just take the first solution that occurs to me, I’ll experiment with different approaches. Let’s see if I achieve that goal!