a story from many years ago when I was working on a traditional software project. When I joined the project team, everyone was committing broken code to the repository. They knew that the build only happened on Friday so they had that long to fix their code. One poor guy was in charge of the build. Every Friday, he pulled the latest code, built it, and then published it out for everyone to use as a base for the next week's development.
Sounds easy, right? Only, the build didn't get finished until the following Tuesday or Wednesday because nothing ever worked. And I'm not talking about broken tests—we didn't have a lot of tests. I'm talking about not being able to get the application to compile for days. It took me about a month, but I managed to get a build server running, train the team on how to properly commit working code (and pull down everyone's changes) and monitor the continuous integration build server for failures.
But that isn't the story. The story is about our teammate who was in charge of the complicated back-end data analysis engine. He was working solo. (No pairing on this project.) He had no automated tests. (You can forget about test-driven development.) And he didn't pull down any changes to the software for three months!
Go ahead and read that last sentence again. For three months he worked in total isolation. He didn’t want to pull down new code because he knew it would break what he was building and slow him down. Shame on us for not catching it. We ended up throwing away most of what he had done and reworking it.
Use Pair Programming
Here's the scene: two developers, one keyboard, one mouse, one large monitor, and one story for them to implement together. Can it really work?
Pair programming is perhaps the most controversial of the techniques we're discussing, but it is also one of the most important. Even at my work in Asynchrony, we continue to have differences of opinion on how much to pair program and how much to go solo. On my teams, the rule is that a pair must write all production code. Individuals can perform tasks like spikes and code reviews.
Pairing gives your team depth and breadth of knowledge. It prevents knowledge silos that often lead to bloated code and time-sapping bugs. The members on my teams change, but we can always absorb new members and get them up to speed quickly. After all, they get one-on-one training from their pair. When someone leaves a team, their particular talents leave with them but the knowledge stays.
Practice Test-Driven Development
Test-driven development is an important extension of automated testing. Rather than writing automated tests after the code is written, a single test is written and then just enough production code is implemented to make the test pass. After the test passes, you look at the code to see if it needs to be refactored to a better design. Then you repeat the process: test, code, and refactor. By doing this, you can find your cadence for methodical, predictable progress. Through that cadence, you continually increase your knowledge of what you are building, how to build it, and how to prove that it is working properly. In addition, the automated tests serve as documentation for the design. Unlike unified modeling language (UML) diagrams or other written documentation, the tests are living, breathing proof that the system works.
Test-driven development is not something that is easy to do. It takes practice and a willingness to change