In the changing landscape of the software engineering industry, streamlining responses to user queries is crucial. Craig McCarter tells us how to do it.
Releasing the highest-priority business value to users every week – it sounds like a distant dream, but at Liberty IT we have been evolving our approach to make this a reality across many of our teams.
One of the critical enablers has been our engineering principles. It boils down largely to disciplined extreme programming ideologies and practices.
Break down knowledge silos
The practice of pair programming is a subject of great debate around development teams, but one thing everyone agrees with is the fact that it is very effective at facilitating knowledge sharing across the team, and eliminating those silos that form over time on traditional projects.
Many of our teams within Liberty IT pair on a daily basis, but they also actively rotate those pairs each day so as to maximise each developer’s exposure to different parts of the system as well as giving all our developers a chance to work with each other.
Each developer brings their own strengths and specialisms to the pairing and, through working with each, you build a deeper knowledge and breadth of experience as well as a better appreciation of the value and strengths of each individual.
Many people have preconceptions about the restrictions and flexibility (or lack of) that pair programming brings to a team. They worry that they will be forced to work fixed hours, taking lunch at a set time and compromise flexible working benefits.
However, we have found that when teams approach pairing with the right attitude and have a willingness to make it work for them, it is reasonably simple to find a model that works for the whole team.
Some of our teams agree their pairing and story allocation at the end of each day, so that as each developer arrives the next morning, they can start developing as soon as they are ready, regardless of whether their pair arrived at the office at the same time or not. It’s a simple matter to catch up on the first pieces of progress made when their counterpart arrives.
For me, one of the important aspects of pairing is that there should be two mirrored screens, two keyboards, two mice. Either developer should be able to reach out and take control at any given time.
Naturally, both cannot control the machine simultaneously and expect sensible results but by introducing ‘pairing parity’, you make both engineers equal, empowered to contribute to the solution, neither one called out as driver or navigator.
This helps avoid some bad behaviours and anti-patterns that can be introduced if a single developer is allowed to dominate the session.
One of the key outcomes of this practice is the building of adaptable teams that are resilient to change, and where every member is capable of picking up any user story that comes their way.
If you want to be able to respond quickly to business need, this versatility is crucial.
Build the right thing, the right way
A product-centric approach, with a strong customer focus, ensures our developers build the right thing. Our teams talk to their product owner every day, understanding the business vision and core values.
The product owner dials into the daily stand-ups to listen to the team’s progress and to share their own input and insights.
Every member of the team is engaged with the business goals and understands the value of each story they deliver.
Put this all together, and you enable the entire team to be much smarter about how they work.
User stories are defined in terms of the business value they deliver, but developers are empowered to consider and challenge the best way to deliver that value, based on their technical ability and understanding of the customer need.
Rigorous test-driven development
In addition, the team’s approach to development – through test-driven development, continuous refactoring, pairing and a highly testable architecture – ensures that our developers build things correctly.
We don’t spend time on triage and defect management. We don’t have to manage large amounts of waste or technical debt. We don’t have the overhead of long business testing cycles.
It is rigorous – a story is not considered complete until we have:
1. Written automated tests to exercise the functionality
2. Written the code to satisfy those tests
3. Manually verified the user experience is consistent with our standards
4. Executed the entire test suite to ensure no issues have been introduced
5. Committed the code to our source control repository, which kicks off another full suite of tests, ensuring our high standards have been followed. It also instigates an automated deploy to our acceptance environment
6. The story has been exercised by our product owner or the local proxy to ensure quality and perform exploratory testing around edge cases
It sounds long and drawn out, but these activities often occur within minutes or hours, never mind days.
Our teams continue to be committed to, and take great pride in, the quality of our solution.
Be responsive to evolving business priorities
When a team starts a new engagement, the first thing they do is to build continuous integration and delivery pipelines.
Within a matter of days, we deliver our first artefact into a test environment in a fully automated manner, having passed a unit test-stage gate.
That artefact may look simple and ugly but the underlying process is beautiful, and it sets the stage for the value that will be placed on maintaining that same pipeline at a high standard throughout the product lifetime.
The ability to commit code to the repository and within minutes – after it has passed through an extensive suite of rigorous testing – have it deployed directly to our business users for feedback is not to be underestimated.
Gone are the days when you wait months for a user acceptance testing phase, or even days until the end of a sprint, before you get feedback from another person on whether your code is fit for production. On our development teams, you could be getting face-to-face feedback within half an hour of committing code.
Couple this lightning-fast feedback loop with short iterations and frequent releases, and you suddenly have a powerful combination that allows you to pivot really quickly and respond to evolving business needs.
Our business product owners are frequently re-evaluating the priority of individual stories, or of entire releases, and that is not a problem.
The teams continue to work on the most important work from the top of their backlogs, and we deliver to production the day our product owner is happy with the functionality that has been delivered.
Faster feedback, better products
Disciplined engineering boils down to one key objective: reduced cycle time and faster feedback. This is a strategic business advantage that allows us to build high-quality, customer-centric solutions, coupled with the ability to react faster than our competitors to emerging business opportunities.
I love to share the anecdote of a time that, following a sales pitch with a large brokerage conglomerate, a product owner came back to their team with new features that were highlighted as important to their users. Instantly, that feedback was converted into user stories in the backlog, where they could be prioritised and scheduled alongside the existing scope. The team picked up those development tasks and had the functionality ready to be delivered to users within days.
If we want to gain traction in emerging markets, if we want to continuously delight our customer base with solutions that are intuitive and continually evolve to respond to their needs in a timely fashion, we need to seriously consider the discipline we apply at every stage in our development life cycle.
Craig McCarter is a software engineer at Liberty IT.