Ayende @ Rahien

It's a girl

Hibernating Rhinos Practices: Pairing, testing and decision making

We actually pair quite a lot, either physically (most of our stations have two keyboards & mice for that exact purpose) or remotely (Skype / Team Viewer).

2013-01-27 14.05.24 HDR

And yet, I would say that for the vast majority of cases, we don’t pair. Pairing is usually called for when we need two pairs of eyes to look at a problem, for non trivial debugging and that is about it.

Testing is something that I deeply believe in, at the same time that I distrust unit testing. Most of our tests are actually system tests. That test the system end to end. Here is an example of such a test:

[Fact]
public void CanProjectAndSort()
{
    using(var store = NewDocumentStore())
    {
        using(var session = store.OpenSession())
        {
            session.Store(new Account
            {
                Profile = new Profile
                {
                    FavoriteColor = "Red",
                    Name = "Yo"
                }
            });
            session.SaveChanges();
        }
        using(var session = store.OpenSession())
        {
            var results = (from a in session.Query<Account>()
                           .Customize(x => x.WaitForNonStaleResults())
                           orderby a.Profile.Name
                           select new {a.Id, a.Profile.Name, a.Profile.FavoriteColor}).ToArray();


            Assert.Equal("Red", results[0].FavoriteColor);
        }
    }
}

Most of our new features are usually built first, then get tests for them. Mostly because it is more efficient to get things done by experimenting a lot without having tests to tie you down.

Decision making is something that I am trying to work on. For the most part, I have things that I feel very strongly about. Production worthiness is one such scenario, and I get annoyed if something is obviously stupid, but a lot of the time decisions can fall into the either or category, or are truly preferences issues. I still think that too much goes through me, including things that probably should not.  I am trying to encourage things so I wouldn’t be in the loop so much. We are making progress, but we aren’t there yet.

Note that this post is mostly here to serve as a point of discussion. I am not really sure what to put in here, the practices we do are pretty natural, from my point of view. And I would appreciate any comments asking for clarifications.

Comments

Russell Allen
02/05/2013 10:35 AM by
Russell Allen

In other blog posts you write about how your team members are able to work fluently across multiple products, without promiscuous pairing how else do you facilitate the necessary knowledge sharing? Code reviews?

Ayende Rahien
02/05/2013 10:38 AM by
Ayende Rahien

Russell, "Can you come over here for a sec" is the most common method. Code reviews are done only on stuff that is REALLY important. For the most part, I trust them to raise a flag if they are sinking.

Andrew Armstrong
02/05/2013 11:02 AM by
Andrew Armstrong

I run a small team and we make use of HipChat (hipchat.com) for inter-team communication while at the office (saves having to get up constantly).

Scrum standups are also pretty handy.

It's also great when you remove yourself as a bottleneck (most recently was setting up octopusdeploy.com so I wasn't the "deploy guy" people had to go through).

Cheers

James McKay
02/05/2013 11:33 AM by
James McKay

Interesting what you say about favouring experimentation over tests.

I've actually started to find the opposite though: I've found I'm relying more and more on my unit tests as a framework to facilitate experimentation. Not sure what a particular C# language feature does in such and such a corner case? Spin up a unit test for what you think it should do and see if you're right.

Also means of course that you have a record in source control of exactly what experiments you've done and what the outcomes were.

Ayende Rahien
02/05/2013 11:34 AM by
Ayende Rahien

James, That is something different. You are doing something that is inherently very small. We are usually talking about things that are larger in scope.

Damian Hickey
02/05/2013 11:44 AM by
Damian Hickey

Prepare for incoming TDD zealots in 5... 4... 3...

But seriously, agree and do same. For new feature development, 'spike and stabilize' http://lizkeogh.com/category/spike-and-stabilize/ .

Too many businesses / teams 'spike and move on' though.

Too many unit tests, I call "Gulliver's Travels syndrome" that can tie you down like this http://boxofficebuz.com/content/movies/316/filmstills/full/2010gullivers_travelswallpaper001.jpg

Of course, it's not all black & white. Unit testing some piece of algorithmic code is essential and bug fixing is failing-test-first.

Damian Hickey
02/05/2013 11:50 AM by
Damian Hickey

Eh, your blog removed the underscores from my url. Alt - http://i.imgur.com/rtLyEZd.jpg

Harry McIntyre
02/05/2013 03:46 PM by
Harry McIntyre

When I do TDD it is using tests like the ones you've written above. So I'm writing a test, probably a system test, but I'm at least doing it before the feature is written. These are definitely not unit tests, though, which are like a thousand tiny wires pulling your code in different directions, holding it statically in place, and in design.

When I'm not TDDing, I'm using exactly the process which is described in the post, which is a bit like rock climbing, securing yourself with tests after clambering forward dangerously. Hope I've hammered those pegs in properly!

AG
02/06/2013 07:43 AM by
AG

It's actually allowed to refactor those tests :) Also dropping those that don't provide any value... they're there (the unit tests) to guide my development. Many of them are some kind of automated experiment that can be redone over and over... And of course not all of them make it to source code repo...

Colin Bull
02/06/2013 12:04 PM by
Colin Bull

On experimentation, this is where the playfulness of having a REPL can be incredibly useful. Once I have something concrete in my script I'll then go and put it into the codebase, then solidify it with tests. I think this is a sorely missed feature in C#, although admittedly not trivial to implement.

meisinger
02/07/2013 06:28 AM by
meisinger

i don't want to come across as being "that guy" but i really can't help myself here...

the test (or spike) shown is named "CanProjectAndSort". clearly it shows that projections can be done but sorting against a single entry? at least throw in another Profile or Account to prove sorting.

i am curious, however, if there is a correlation between unit tests and system tests with behavior and state. in other words, if i want to validate the expected state of an operation i would perform a system test (or spike) while validating the behavior would be a unit test.

as Damian point out, however, it's not all black and white

Ayende Rahien
02/07/2013 09:05 AM by
Ayende Rahien

Mike, We are testing that specifying order by doesn't throw. The actual sorting behavior is tested elsewhere.

Jim
02/19/2013 07:49 AM by
Jim

@Colin Bull, I find the immediate window in a visual studio debugging session handy for REPL type duties.

Comments have been closed on this topic.