Sunday, July 28, 2019

Team Scars


You know those signs in every shared kitchen? “Please rinse your dishes and put them in the dishwasher”, “please don’t leave food in the fridge over the weekend”, &c? They happen because people were piling dishes in the sink and letting food rot. Something had to be done, and the sign was the result. You may meet people that are imagining signs like that around unexpected aspects of their work. It can be surprising because these signs are invisible.

“Ticket validation should be a separate stage in the workflow”. Why? Why not? This isn’t an objective proposition, it’s reaction to shipped bugs that more careful validation might have caught. So a manager adds a step in JIRA... which is completely pointless unless the team agrees to actually do more testing. Just as likely, the developers now resolve and validate where they used to just resolve, without changing anything on shipped quality. Dang, the kitchen is still dirty! So maybe a developer speaks up.

“Please write unit tests for all of your code,” says Alice. She’s sick of being on call for dumb logic errors. Like washing the dishes, this is a shared code hygiene issue, and hard to argue with. A unit test is an alarm that the code might no longer be working as intended. It costs little, and it’s helpful. A policy that you should have one at check in? That’s a helpful reminder. But a policy without enforcement is really a guideline, so maybe Bob wants to talk carrots and sticks: But now there’s resentment, because Charlie doesn’t agree with the goal. Worse, they may be right.

Each team member brings their past experiences to this conversation, and can easily spend a lot of time talking past each other. I’ve had one very bad experience and several mediocre ones with test-driven development teams, so I’m biased against the concept even though I appreciate the theory. I have to focus on being constructive and evaluating each new proposal for TDD on its own merits.

That’s how to do the job... what about who’s doing what job? Defining the actual roles that team members are going to play is an even bigger minefield. “Product managers should be technical enough to engage in code reviews” ...or is it “Product managers should be so non-technical that they can’t follow the standup”? “Teams should have dedicated quality assurance engineers” versus “Developers should take full responsibility for code quality.” There are software people out there who’ll passionately argue for any of those statements. That passion might come from recently reading an Agile textbook, but it’s more likely to be from remembered experience. “Darlene was really helpful, she’d even fix bugs between customer calls!” “Eddie was kind of a seagull, but he was too scared to bother us much so that was okay.” “Frankie gave clear direction and then got out of the way.”

As long as someone is doing the various tasks that need doing, the team can still be successful no matter what. But the larger organization wants to see repeatable results and clear accountability, so it’s not great to have paper PMs writing code while paper engineers define requirements. Furthermore, in software culture the work occupies most of our time and headspace. Our job function and personal identity can become tightly interwoven, which makes questioning of that function feel like an attack. “What would you say you do here?” Sometimes a well-intentioned role re-definition leads to angry resignations, as when a field engineering team is asked to do more consultative selling and less field repair work.

What to do and who will do it. These are all people problems: mental models that need communication, a shared consensus that needs building, a plan that needs to be followed. The only way to get there is to talk it out. Woe betide the team imagining one-size-fits-all technical solutions.