Let’s take a look at the top 5 Agile Engineering practices that are essential to succeeding with Scrum and overcoming the struggles team face with trying to deliver a Product Increment at the end of each and every Sprint.
Test Driven Development (TDD)
TDD is a development practice where we start with a very small automated test about functionality we are about to build. The test fails because the code we are testing against does not yet exist. We then write enough code to make the test pass. Then we go through a very important step called refactoring. In refactoring, we clean up our code, updating and improving the internal implementation while all along ensuring that the test still passes. Once we are happy with the implementation, we move on and add another small test and we repeat. This approach is how we build things iteratively and incrementally. It helps build up the skills needed to build applications in small iterative and incremental steps. In addition, the refactoring and regularly improving the implementation and design ensures that our code is built on a solid foundation and we are building quality in. A side benefits of TDD is that we have an automated test suite. By the time we are done coding, we are also done testing with most of our functional testing that proves the code works as intended. Testing is no longer a phase done at the end but an ongoing activity that happens throughout. These tests can be hooked up to the continuous integration server and run over and over again and become part of our regression test suite. So this one practice helps us tackle a lot of the issues we highlighted earlier in terms of test automation, building quality in, and building iteratively and incrementally while ensuring we always have a working version of our product up and running.
Pair programming is a practice where 2 developers work together on the same problem at the same time. We have a driver that is writing the code and thinking tactically about the problem and a navigator that is observing and providing feedback while looking at the big picture. This helps with breaking down the silos and building quality in or pushing it to the left. We automatically get collaboration and knowledge sharing. Sharing of both domain knowledge and technical knowledge. We also get an improved design by having 2 people work on it and address it from different perspectives. In addition, instead of waiting until the work is done to do a code review, we get an early quality check by doing a real time code review. This helps us catch and fix defects early and improve the quality of our code base.
Ensemble or mob programming takes pairing and turns the dial all the way up to 11. We are working on the problem together as a team. Instead of just sharing knowledge between 2 team members like in pairing, we are spreading that knowledge across the team. This has a direct impact on quality and further breaking down the silos and bringing us closer to collective code ownership.
Collective Code Ownership
Collective Code Ownership means everybody on the team owns the code. We are no longer dependent on 1 person. We don’t have to locally optimize our work based on who is available and what skills do they have. The entire team owns the code. We don’t just go to Jack to work on the accounting module or to Lisa to work on the billing module. Having the team exposed to different modules of the application means anyone can go in and make necessary changes. They might not be able to go in and do some heavy lifting, but they are knowledgeable enough to go in and make updates as needed. This eliminates bottlenecks and allows the Product Owner to prioritize the work based on value instead of based on who is available in order to keep everyone busy.
Continuous Integration and Deployment
CI/CD is a practice that allows us to have the latest working version of our product up and running. It reinforces the approach of building applications iteratively and incrementally. Whenever someone makes a change, that change is integrated with what was already there and gets deployed. It also helps with building quality in as the change goes through a suite of automated tests ensuring that we did not introduce any new bugs. It provides us with a safety net giving us the courage to regularly accept and make changes as well as improve the code base without the fear of breaking things. It eliminates the need for code freezes, makes testing cycles super short, and ensures deployments are successful.
Now that we covered the Agile Engineering practices, let’s address some of the struggles teams face in adopting these practices.