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:

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

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'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.

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.