I strongly believe that good user stories should articulate the problem to solve and for whom (typically stated as “As a role, in order to solve a problem, we want a suggested solution“), and that these stories should ideally provide a real, immediate and tangible value.
I work as a test automation architect as part of an automation infrastructure team in our company. Before that team was formed, different teams created separate automation projects by copying the infrastructure code from one another. Obviously, over time this code started to diverge, as each team started to make their own changes, as often happens with duplicated code. Now, one of our main goals as an infrastructure team, is to remove this duplication by creating reusable component (.Net NuGet Packages).
While I totally see the problems with duplicate code and the benefits of creating reusable components, I have hard time articulating this value (let alone, as being immediate and tangible). The point is not how to phrase that sentence, but really how to split the work into small valuable, deliverable pieces that provide immediate value for the teams, and to prioritize them.
Clearly, I see that our main “customers” are the teams that write and maintain their distinct automation projects, and that by creating these reusable components we alleviate the maintainability burden from them and take it on ourselves (in a concentrated and more effective manner), but that seems like a pretty vague and long-term problem, and not as something that provide tangible and immediate value.
I guess that the same question can be generalized to any tech-debt stories, but when the tech-debt is inside one team/project, the team can clearly see the benefits of removing it, while in my case, where the tech-debt is across teams, each team feels like they can better solve their own problems but they miss the big-picture of the company-wide problem (waste) that is going on.
I’d like to hear your opinions about this situation: Would you articulate the stories in a different way? should we focus on different short-term value? Do we focus on the wrong things? Or any other insights you might have.
Before answering the question, we have to keep in mind the trade-offs that are involved here.
When you centralize this type of things, you will indeed reduce the maintenance burden on all the other teams, but you also introduce an organizational dependency between the teams.
What I mean is that teams won’t have to worry about fixing problems in the shared code, however they also won’t be able to have new features they need until your team is free and ready to implement them. This type of things cause conflicts between the priorities of your team, and that of other teams (or even between other teams, if they both need different features at the same time).
Now to answer the question more directly, there is an immediate value only if you are trying to roll out an organization-wide change that will affect all automation pipelines.
Otherwise, I’m afraid there is no immediate value in this case. Duplicating code never really causes significant issues right away, it’s always a problem that develops over time. Usually the issues that crop up are caused by the fact that duplicate code contains duplicate bugs, or caused when a change that impacts all automation has to be implemented (there will always be some people lagging behind).
Maybe a better solution would be to write your automation code such that teams are able to extend it. Keep a common core that takes care of the typical usecase, but provide hooks that individual teams can use to customize the behavior.
Do we focus on the wrong things?
Most probably: yes. Let me first say I backup LordOfThePig’s answer, in that the extra organizational dependency introduces a high risk and may be not worth it. Several years ago, I had been working in a huge project which heavily underestimated that risk, which actually was one reason why after five years the project was canceled.
However, to give you a more positive answer, lets focus on an approach which still might sometimes work, at least when there are several teams in your organization developing a lot of duplicate things.
Lets start here:
Clearly, I see that our main “customers” are the teams that write and maintain their distinct automation projects…
Ok, here are your users. From their perspective, ask them what new kind of “standard components” they would actually love to get delivered by some 3rd party (your team), so they don’t have to develop them by themselves. Of course, your team will only offer standard components which you expect also to “sell” to other subteams, so the different teams don’t have to develop them twice.
Hence, if you are going to work with “user stories”, write them from this perspective, like – “as a dev from the billing department, in order to let our program communicate with our new centralized logging system, I would like to have a standard API for this”.
and that by creating these reusable components we alleviate the maintainability burden from them and take it on ourselves (in a concentrated and more effective manner), but that seems like a pretty vague and long-term problem, and not as something that provide tangible and immediate value.
That’s probably because you only look at maintenance and try to focus on things which are already there. Bundling such things in one new component is rarely worth the issue – it only creates a refactoring burden for all the teams who have to replace their working code by a new centralized one, with no immediate benefit for their “customers”, but a certain risk of introducing new bugs.
But maybe there are new requirements which require really new components which haven’t been developed so far. Or at least, there may be a technical need of a greater renewal of existing things, where each of the existing teams has to rewrite or adapt their copy-pasted code from the past in a similar manner. When your team can provide a solution here, so five other teams can save the hassle of doing very similar work five times, I think that is a pretty tangible and immediate value.
Finally: don’t underestimate the challenges of writing components which can be easily used by different teams, with all their individual specifics. This is where the SOLID principles become important, opposed to standard “application” code, where too much SOLID sometimes leads to overdesign. For creating reusable components (especially “black box” components), providing the right extension and parametrization points is crucial, as well as providing good documentation. The effort will be easily three to four times higher than when you write non-reusable components (that’s why it will only pay off when you have at least four or five teams which can actually reuse a certain component).