Almost a year and a half ago I started a journey with a team. I wanted to embed myself in XP practices. I wanted to learn how things looked so I could maybe one day be better at helping other teams adopt some of those practices. Below are some observations about my own learning and that of the team’s adoption.
You may notice the use of “I wanted”. The team didn’t necessarily want any of this. They simply were writing software. Getting frustrated with writing the tests they were writing. But they were happy enough.
Some of the things that I’ve learnt
– TDD is hard
– TDD isn’t adopted unless a 1:1 mentoring process happens on the real code that is being worked on. Understanding is very important. But showing how to apply it on real code that is part of the sprint delivery is even more important. Showing that someone else (who hopefully has an idea of what they are doing) also runs into pitfalls on how a legacy code base is designed for testability – and showing some patterns to work around those problems – all while coding for a real deliverable on the system helps embed understanding and buy in to trying.
– TDD isn’t adopted unless at least one person champions it and the majority of the team are willing to be influenced and open to try. One person championing it and no one else caring or trying will fail. The more people who buy in and can help pair and show the process the higher the probability of success.
– Pairing while continuing to adopt TDD is very useful. Your partner helps keep you honest. You can discuss how to test what you’re trying to do. You have a shared cognitive experience and learn together.
– Code coverage can help you understand if someone is trying to do TDD or not. If there is none – it is obvious that TDD isn’t being done. That can help to spark conversations. (But of course, code coverage numbers aren’t important – none, some and lots are what is. And anything more than none doesn’t mean TDD is happening, just tests, but that is better than no tests!)
– Pairing is hard.
– Pairing with juniors who know the domain can be very useful. Having two thoughts on the design and the requirements in order to validate understanding, to think out loud and even model out loud can be very valuable. Pairing with someone completely new can however be frustrating for all sides. Then it becomes pairing for learning, which is a different way of working again.
– It can be too easy as an architect to not pair as there is other non-sprint work to be researched, meetings to attend, code reviews to be done. I personally need to pair more and find ways to not do “other” work. Or to do it as a pair.
– Design is hard.
– Better designs will emerge by the need to test due to the need to decouple. More cohesive designs may emerge if you’re careful. But that requires understanding of what that means and looks like. Doing TDD doesn’t lead to good design. Being able to see the patterns in the code and to extract them into a good design leads to good design. TDD gives you the time and freedom to do that. But if your team can’t see it then TDD will only help you with your test coverage…
– Conversations about design will emerge and better architectures can be adopted that keep the code simpler. Keeping the code simpler makes it easier for everyone. The design remains simpler. It is easier to not make a big mess as you’re watching for it getting complicated… if you’re designing.
– We don’t do continuous integration. Most people in the team don’t care about a build on commit. No one sees the burning need to deploy automatically. I haven’t pushed it as no pressing problems exist that would obviously be fixed by introducing CI. I’d rather finding places where the need could be more easily validated and leverage those. That said – a recent deployment showed up the desire to have an automated deployment for much faster turnaround on testing a new build so maybe there is a place to get people more interested and perhaps when that is there the understanding and desire to keep it going will grow.
How did we get here?
Over the last almost year and half I’ve shared my views on pairing, TDD, refactoring, agility in code – principles like the simplest thing, fast feedback and emergent design. Some of them the team have chosen to try. Some have reacted very negatively to some of the ideas. I haven’t pushed any too hard. I’ve led by example doing it myself. I’ve put effort into explaining the reasoning and thinking behind ideas. I’ve gained a deeper understanding of why I do things. And the ability to question the way I do things at all times based on a desire to optimise the agile values and principles, not worship the agile practices.
As a result of this we’ve circled in from testing sort of, after the fact, because we were told to. Around to understanding how to test, what to test, and how to test first – but not necessarily testing first. To pairing – the practice most quickly adopted – and with me driving it less. To now having almost everyone TDDing – and those that aren’t doing that or pairing are starting to visibly fall behind in skills.
I do not think any of this would have been possible without someone showing and explaining from an embedded and trusted state in the team. Outside coaching or training doesn’t stick. I’ve talked to several people who’ve trained TDD and don’t do it at all. I’ve tried for a couple of years to coach people into TDD as a ScrumMaster and PM with many attempts and zero success. Embedding and mentoring can succeed. But it takes a long time.
Where to from here?
I don’t know how much further this team will manage to go into XP or any other agile practices. But I do already know they have come further than I imagined a year ago. And that is awesome. Hopefully we’ll continue to circle in on good XP, better agile practices and possibly – more importantly – get some really good design going as well. The scene is now set to allow that to happen.