The November SUGSA event featured Austin Fagan talking about what makes an exceptional team. A collection of exceptional people doesn’t necessarily make an exceptional team – and Austin posited that the usage of exceptional practices is what can turn a collection of individuals into an exceptional team.
Having experienced a team that is definitely more than the sum of the individuals – I can emote to the sentiment. And equivalently having worked with some exceptional individuals in the distant past – there wasn’t a great deal of real team work. Collaboration and other solid development practices make a huge difference.
The evening included a sequence of “does your team do X” slides – sit down if no, stand up if yes. I was glad that I could at least stay standing for many of the soft skills – empowered team, collaborating, working as a unit, etc. But sadly as always the practices of software development like pairing or TDD are lacking in adoption in my personal experience.
The evening proceeded with a session where we broke into groups and then discussed a topic. We landed with pairing and were looking at issues around what is stopping you from starting to pair today as well as how do you keep pairing when you have started.
Pairing is an interesting thing to me in terms of adoption but it was refreshing having the conversation with some people who are dedicated agile people all coming to the same conclusion. Our summary was something along the lines of “It could be awesome, we don’t really know, so we should try it to find out”.
The standard pros came up – continuous knowledge sharing, no dependencies on a single person, continuous code review (or at least code discussion/justification which should make better code and sanity checking of code), potentially more productivity (can’t work avoid on the internet in a pair as easily).
The standard cons also came up – it wastes time, you need to synchronise office hours for pairs, some developers can only work alone, how do you know it works, we’re changing the way you work while having no evidence that it really does work.
Sadly in the world of development practices there isn’t a lot of evidence in the public domain for software practices such as pairing – just a lot of anecdote that it is the Agile Way. I believe there is some evidence on code reviews – which lends some credit to pairing being beneficial – but not much that anyone sites emphatically to prove that pairing delivers better software, faster, more bug free, or some other quantitative measure in comparison to not pairing, or pairing just some of the time. Though I suspect in the world of delivering business software not too many are going to provide the data for the experiments. I know there is some evidence for certain design practices – such as DDD – to spread the logic and hence the complexity across all the objects hence reducing the maximum complexity of any one object.
Pairing adoption is a tough one. I never did much pairing in my time as a developer or architect. I now wonder if I should go back to learn how so that I can be more emphatic about it one way or another. In fact, I’ve never experience anyone really pairing – by the definition of doing it all day, 1 machine between 2 people, writing code (and tests). Obviously developers pair in order to solve hard problems sometimes, or when there is a slog of work to get through which is more effective with one person typing and one person following the documentation for implementation (read really big CRUD screen), or when their machine is acting up and there is nothing else to do. But I haven’t worked with any developer who actively wanted to pair on a regular continuous basis. I’ve met many who vehemently dislike the idea. And some who’ve tried it and discarded it.
We dug into this a bit and all agreed the biggest issue around pairing is “What is pairing” – what are the pairing patterns – and how do you do it right. I’ve recently read this InfoQ article which talks to pairing as a pattern. It is an interesting read if you’re trying to think through the options – but it’s by no means the answer.
Doing it wrong is going to be detrimental to your ability to adopt pairing as it’ll give those who “know” it isn’t going to work more ammunition to inspect and adapt away from pairing. The key things seem to be training and experience – working with an experienced pair programmer to understand how it works. That is a tough one as I suspect it’ll take a reasonable amount of time immersed in the performance of pairing to learn what the steps are automatically. Pairing seems to be one of those things, like TDD, that possibly is a performance art that one can only learn properly by seeing it working properly in order to reach those “Ahah!” moments.
TDD on the other hand – or at least automated testing – is a lot easier to sell in terms of why to do something like it. I’ve spent a bunch of time pondering pairing and TDD and other practices. Pairing as described above I find harder to sell. TDD on the other hand – or BDD, test first – even test last – I’m more than confident to sing the praises and provide the high level problems that we’re solving. I want to be able to release without doing a full manual regression test over the next month – how do I do this? I’d like to be able to do a quality release every 2 weeks – how do I do this?
I worked on system that we released every 2 weeks to production that had no testers and a full suite of automated tests – it was incredibly successful at deploying often. At this organisation I mostly did test last but it was always very valuable doing the testing. I would do it test first if I were to do it again as I think it might be faster than test last and the capability to test your design as you write it seems appealing. I did a little bit of test first at the start of my time at my current organisation as it allowed me to determine how I wanted to call the code and that defined how I built the outer bits. That was very valuable. It didn’t last though due to my lack of dedication and shifting roles – though the original tests that I wrote were still being used to refactor that code 2 years later and saving the developer’s bacon.
Automated testing adoption
The key failure that I’ve been finding in adopting automated testing – TDD or otherwise – has been in the lots of little gotchas when the system isn’t as testable as you’d like. In the organisation where I was successful with this we were using Perl and could simply modify functions on the fly in tests. It was awesome, but really dodgy from a purist computer scientist point of view. In .NET this is harder. And if you don’t plan for testing in your architecture up front, retrofitting it is a pain.
Fundamentally my experience with automated testing is that developers can be convinced of the value and can get excited about getting it done and including it into every build. But each time you hit another large wall in the way of getting a new type of problem solved in a sustainable and non-fragile way the closer the enthusiasm comes to falling away. The frustration seeps in and the dedication seeps out. That is sad. And it is what makes TDD and any type of automated testing hard to sustain.
Are we doomed to fail at these practices?
I don’t think we’re doomed to fail at these practices. But I do think that we need to think long and hard as to why we’re doing some of them so that we can continue to keep the enthusiasm and dedication up in doing them.
Fundamentally the software developers I’ve worked with over the years – myself included – have a lot to learn about how to make these practices really work for them and the organisations they work for. I’m hoping someday I’ll have learnt some more and will then be able to help others to understand and justify to themselves why these are awesome practices. I’m looking forward to that day – as then I should be working with exceptional practices in exceptional teams hopefully also with really exceptional people. And it will be beautiful.