Friday, April 25

Buckets of mice

We have 24" and 30" pairing stations, an intern, freshly roasted coffee delivered weekly, a fridge stocked with caffeine, more caffeine, beer, and Dave's Insanity sauce. We have cool t-shirts and all manner of radiators up on the walls, whiteboards and the Beta Brite. Music is served by our CI/Music server.

The bookshelves are stocked with reference materials, the occasional bottle of scotch, and recommended readings. On the list of recommended readings we've got The Carpet Makers, The Company, The Omnivore's Dilemma, The Eyre Affair, Behind Closed Doors, Bloodsucking Fiends and The Deadline, Men In Hats, Volume I, Don't Make me Think, The Insane are Running the Asylum.

Our favorite radiator is the Friday radiator. Fridays are special: we don't do billable work. Instead we open source, blog (self reference makes this blog entry extra cool), watch educational movies, play Wii on the projector. Here's today's:

Oh, let's not forget the buckets of mice.

This blog entry inspired by another excellent business card cartoon from Hugh Macleod.


Wednesday, April 16

cmd line history meme

Rob tagged me. So:

muness$ history 1000 | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head
102 git
72 ls
63 cd
40 ss
35 rake
24 m
17 up
14 st
12 sc
11 ri

Tag, you're it.

Friday, April 11

Distributed Retrospectives

Agile Retrospectives (Esther Derby, Diana Larsen) and Project Retrospectives (Norman L. Kerth) have been a great resource in facilitating - or helping others facilitate - retrospectives. I'll often leaf through them a day or two before a retrospective to remind myself of the framework (more on that in an forthcoming post), and to introduce new activities or create my own.

Something that neither of those books tackle directly is how to facilitate a distributed retrospective. Given that we've been running a few of those lately, I wanted to share some tips:

  • Your equipment matters. It took us a while to find a speaker phone that worked well for those in the office and those on the other end. It's hard enough to communicate effectively without being in the same room, without muffled voices. We use a Polycom unit with two extensions for a 20x16 room.
  • Prepare. There's a lot of preparation that goes into running a retrospective in person. You have to familiarize yourself with the project, look for a theme, send out invitations, pick activities (and backup activities in case one isn't working), and collect the tools/resources you need for those activities.
  • Google Docs is your friend. With its near real time updates for viewers and collaborators, it's been an indispensable tool to take notes. The facilitator or a scribe can update the document and others can see what's happening, on the fly.
  • It's not enough to use a Google Doc, you need to turn it into an online workspace that makes others feel like they're part of the process. For example, I prepare a google document with activities scheduled for the retrospective. I take care to:
    • Clearly state activity names. When we move to the next one, it's enough to say its name and everyone can easily find the appropriate section.
    • Describe the activity. Having a written description allows people who miss the spoken description to follow the intent as well as the process involved. Missing a description over a conference call can happen for all sorts of reasons, from people being more easily distracted, to phone problems.
    • State the targeted time for the activity. People are even more restless on a conference call. This gives them a sense of the overall meeting's timeline.
    • Copy or summarize information from previous retrospective documents for ease of reference.
  • Share with others. Sharing the document with others as collaborators (rather than just viewers) gives them the confidence that they can correct mistakes.
  • Don't forget to send an email shortly before the meeting that serves as a reminder, repeats the phone number/conference line details and includes a link to the Google Doc for that meeting.

I've shared a Google Doc template for a 2 hour iteration retrospective for 4 to 8 people you can refer to or use as a starting point for your own living retrospective document. Credit goes to Agile Retrospectives for the activities.

Testing declarative code

For a while now, I've had my doubts about the usefulness of one aspect of test driven development (which applies equally well to behavior driven development): that it should be done 100% of the time.

The first time I came across this, was at ThoughtWorks. The question was whether we should TDD declarative delegations. I remember a several hour long conversation about the merits of tests for Forwardable based delegations.

class A
  extend Forwardable
  def initialize(b)
    @b = b
  end
  def_delegator :@b, :some_method  # Should I write a test before writing this declaration?!
end

A specification for this declaration would be:

describe "A" do
  it "delegates some_method to b" do
    a = A.new(stub(:some_method => :x))
    a.some_method.should == :x
    # or you could use the Handoff assertion:
    assert_handoff.from(A.new).to(:@b).for_method(:some_method)
  end
end

I didn't get the fuss -- it was clear to me that testing such delegations was wasteful and a maintenance hassle. But I didn't realize that this was part of a larger argument.

Not an isolated case

Since then, I've learned that to some developers this is a general rule. Here's another example, re testing stock ActiveRecord validation declarations, e.g.:

class Model < ActiveRecord::Base
  validates_presence_of :attr_1
end

The test for this would be:

describe "Model" do
  it "validates_presence_of :attr_1" do
    model = Model.new
    model.valid?
    model.errors.on(:attr_1).should == "must not be blank"
  end
  # or you might write a helper that reflects on validates_presence_of declarations
  test_model_validates_presence_of Model, :attr_1
end

It took me a while (too long) to get the general pattern: these discussions I kept finding myself in all had to do with testing declarations.

How did we get here?

Test driven development as best as I can tell is a - pragmatic - descendant of formal specifications:

"A formal specification is a mathematical description of software or hardware that may be used to develop an implementation. It describes what the system should do, not how the system should do it. Given such a specification, it is possible to use formal verification techniques to demonstrate that a candidate system design is correct with respect to the specification."

Writing formal specifications for the majority of the software isn't practical. Writing tests first provides us a simple, practical way to write executable specifications. True, they don't give us the ability to use "formal verification techniques" to prove anything about our code, but they do give us confidence that our code does what our tests say the code does (as much confidence as we have in our tests).

The rule

The rule regarding TDD is: If you can TDD it and it's destined to be production code, you should TDD it.

The problem I find with this rule is that it causes us to write tests like those above that duplicates the declarative code. At best case it goes like this:

  # We write this code first in the spec:
  test_model_validates_presence_of Model, :attr_1 
  # we run it and watch it fail...
  # and then we write this in the model class:
  validates_presence_of :attr_1 
  # rerun the test and watch it pass...

I find this wasteful: We first implement the test_declaration_is_called (in this case, test_model_validates_presence_of) for every declaration. After all that work (and not to mention code that we have to maintain) we end up with a test that tells us what the declaration itself does. But with less readability and intent. Indeed, declarative code is in fact formal specification.

Guidelines not rules

Writing tests first is a great guideline. I do it almost all the time. But I don't do it all the time. It makes me angry when I change declarative code only to have a test that looks exactly the same fail as well.

OK, tests for declarations don't really make me angry. But they do make me wonder if the developer who wrote the test really likes to answer the question, "are you sure that you're sure that you want to do what you just said you want to do?"

Friday, March 14

Where there's smoke signals...

In a previous post, I briefly described how we were using cc_campfire_notifier to get build success/failure notifications in campfire. cc_campfire_notifier has lost momentum over the last couple of months. Since we actively rely on the notifier for several projects, we've now forked it as smoke_signals.

The first release offers the following improvements:

  • Each notification includes a link back to the CruiseControl.rb build (so you have one-click access to the full details for each build).
  • Recognizes apr_error errors as SVN errors (so you'll spend less time scratching your head over generic build failure messages).
  • Speaks once into the campfire room whenever an unexpected error occurs (as opposed to speaking once per line in the backtrace).

Check out the notifier's home page for installation instructions or head on over to GitHub to browse the code.

Thursday, March 6

Release early, release often, business edition

One of the things we preach as software developers is release early, release often. I think ESR is right in that our primary motivation for this is often related to quality:

In the bazaar view, on the other hand, you assume that bugs are generally shallow phenomena—or, at least, that they turn shallow pretty quickly when exposed to a thousand eager co-developers pounding on every single new release. Accordingly you release often in order to get more corrections, and as a beneficial side effect you have less to lose if an occasional botch gets out the door.

As I've done more project consulting and management, I've realized that the benefits extend well beyond the technical ones. But I've had a difficult time articulating the business benefits to incremental, frequent releases.

Last week, Ross posted an article that describes one of the primary business benefits to frequent, early releases, Minimising the Speculative Risk of IT Investments:

With each incremental delivery, and every increase in tangible value, the intangible or speculative value decreases. The reduction in speculative value at risk represents a reduction in the total value that can be depressed through delays in delivery. Thus, early delivery reduces the risk of speculative value not being realised. Simultaneously, it reduces the volatility of returns.

What other benefits do you find to the business from releasing early, releasing often?

Thursday, February 7

CC.rb Campfire Notifier Released

Note: I've forked this notifier to add features and fix some bugs at in Smoke Signals. At Relevance, we make heavy use of Campfire for our distributed projects. One room per project, and we expect everyone to "be in" the relevant room associated with the project they're working on at the time. We use it to communicate: to ask for a pair (we've tried Leopard's Remote Desktop Sharing, but have no settled mostly on emacs + screen), ask questions, request code reviews (we've taken to using the topic for posting ad hoc requests like that), and make announcements.

This virtual space has many disadvantages over being in the same room as I'd been used to on my previous couple of projects, but it did have a nice perk: SVN commit notifications were right there alongside our own discussions. The notices were more useful than I expected, a quick, clear indicator of our pace on a given day.

Naturally, I wanted our other major automated task to notify us of CCMenu is OK, but it's disconnected from our primary virtual space (Campfire, as discussed above). Being lazy, I didn't want to build it myself, so I first looked around for tools that suited my needs. Much to my chagrin, none did, so I took the one that was closest and added to it what I needed: specs. Then came the stuff that was missing: ssl support and support for one room per project. And last but not least, to help deal with configuration hassles and debugging, I added logging.

If you're using CruiseControl.rb and Campfire, give it a whirl. Instructions are in the README.

Tuesday, February 5

Pi

Sunday, January 20

Managers and rules

Jerry Weinberg, if you don't know him, is the author of more than a dozen books on software development and memorable laws such as the Law of Twins. In Quality Software Management: Systems Thinking, published in '92, he described what we might today call an agile team. (He lists several levels of software team cultures, ranging from Oblivious to Congruent. Along that spectrum, an agile team would fall somewhere along Steering, Anticipating and Congruent.)

At AYE 2007, I had the pleasure of meeting Jerry in person. Something that I was not aware of was his remarkable skill at helping others. Instead of answering a request for advice directly, he'd delve into the details, applying something like the 5 Whys. Within minutes, he would hone in on a rule that the person had imposed on themselves that was at the root of the problem. After expressing the problematic rule, he'd help them relax the rule into guidelines. Several people who've spent more time with him have echoed my gut feel that they too found this ability to help others rare and invaluable.

His approach to helping individuals is based on Virginia Satir's work in family therapy on survival rule transformation. An excerpt from The New People Making:

After you have written down all the rules your family thinks exist and cleared up any misunderstanding about them, go on to the next phase. Try to discover which of your rules are still up to date and which are not. As fast as the world changes, it is easy to have out-of-date rules. Are you driving a modern car with Model T rules? Many families are doing just this. If you find that you are, can you bring your rules up to date and throw away the old ones? One characteristic of a nurturing family is the ability to keep its rules up to date.

Now ask yourself if your rules are helping or obstructing. What do you want them to accomplish? Good rules facilitate instead of limit.

Last weekend, while attending a Satir workshop I was struck by the applicability of Satir's ideas on rules to teams at work. There too, rules can be unstated, ambiguous or inapplicable sometimes hampering our ability to get things done, other times making everyone miserable.

(For a valuable discussion on rules suitable for software development teams, check out the section on Rules in chapter 21 of Software Teamwork:Taking Ownership for Success. To summarize, the rules should be focused on ensuring that a team has "the capabilities and resources to do the right things, rather than on stepwise procedures to be dogmatically followed".)

In big companies the problems are magnified as fully connected networks of people become prohibitively expensive. For example, it'd take each person over a day out of every week for 25 people to stay in meaningful weekly one-on-one contact. (Indeed, the few who take the time to build an extensive network can become stars capable of getting things done faster than their peers could.) Additionally, in a big organization, it's likely that a rule that works for one group will be applied to ones where it doesn't fit.

The role of a manager is to engender an enabling environment. But how? Virginia Satir's approach to rule transformation provides one way. One which fits in well with the management advice in many of the management books I am familiar with, including Behind Closed Doors, Peopleware and Slack.

Here's how I describe the process:

  1. Identify implicit rules and restate the explicit ones.
  2. Explore how they came about.
  3. Express the rules explicitly.
  4. Clear up ambiguities in the team's understanding of each rule.
  5. Evaluate each rule's applicability.

Having done this, you might find that a rule is:

  • Helpful and reasonable. So, apply it!
  • Helpful but impossible or untenable. Then transform it into one or more guidelines that aren't prohibitive.
  • Limiting or obstructing your team. If so, the rule should be challenged, publicly.

Again, quoting The New People Making:

What do you think about your rules? Are they overt, human [i.e. reasonable] and up to date? Or are they covert, inhuman [i.e. prohibitive, impossible] and out of date? If your rules are mostly of the second variety, I think you realize that you and your family [or team] have some important and necessary work to do. If your rules are of the first category, you are probably all having a ball.

Saturday, January 19

spec-converter 0.0.3

Inspired by a link Rob sent to a blog entry on converting Test::Unit to Rspec, I added the ability to convert assertions in spec-converter, as follows:

  • assert !foo with foo.should == false
  • assert foo > 20 with foo.should > 20
  • assert foo with foo.should == true
  • assert_equal y, x with x.should == y
  • assert_false foo with foo.should == false
  • assert_nil foo with foo.should == nil
  • assert_not_nil foo with foo.should.not == nil
  • assert_true foo with foo.should == true

Enjoy your conversion. ;)