Hibernating Rhinos PracticesPairing, 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).
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.
More posts in "Hibernating Rhinos Practices" series:
- (22 Feb 2013) A Sample Project
- (06 Feb 2013) Design
- (05 Feb 2013) Pairing, testing and decision making
- (04 Feb 2013) We are hiring again
- (31 Jan 2013) Development Workflow
- (30 Jan 2013) Intro
Comments
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?
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.
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
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.
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.
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/film_stills/full/2010_gullivers_travels_wallpaper_001.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.
Eh, your blog removed the underscores from my url. Alt - http://i.imgur.com/rtLyEZd.jpg
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!
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...
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.
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
Mike, We are testing that specifying order by doesn't throw. The actual sorting behavior is tested elsewhere.
@Colin Bull, I find the immediate window in a visual studio debugging session handy for REPL type duties.
Comment preview