At a minimum, the Scrum Master should to realize whether the team is aware of what they're doing - and if they aren't, bring in a technical coach or senior developer who can teach the team the ropes. There are many nuances, and a non-technical person will not see everything. Once developers are on the right track, they can very well figure out where they need further help.
tl;dr: of all the categories below:
Absence of the practice causes delay, incurs cost, reduces stakeholder satisfaction and may kill the product (and in smaller organizations, the business!)
Here's what to look out for:
AutomationPhrased positively: If we do indeed automate everything that can be automated, we gain a much better understanding of what's actually needed to get something to work. Automated activity also frees developer's heads for doing new work rather than repeat activity. Everything automated can be tested, so we can test not only the software but also the meta-processes, bringing quality to another level. We create repeatability, reliability and confidence in the processes.
Plus, we eventually save time.
Dead giveaway? Team members have paper (or electronic) documents for standard activities they do all day.
Constant RefactoringRefactoring should be a day-to-day activity as part of regular work. Every line of code should be refactored as soon as it becomes necessary.
Deferring refactoring will eventually put product development to a screeching halt, which can be fatal for smaller companies. I have seen products die entirely because one day, developers discovered that new features couldn't be integrated any more without breaking something else.
Dead giveaway? Developers complaining about code quality.
Unit TestingOver the months/years, code will become more and more difficult to maintain unless there's a decent amount of unit tests. The time it takes to make even minor changes will explode in the absence of good unit tests: What might take seconds with unit test coverage could take weeks in untested code.
Dead giveaway? The "tests" folder in the repository doesn't get updates with every new version.
Continuous IntegrationProblems in the codebase are often not visible until the latest version of the build (which must be subject to automated tests) has been validated. In highly complex environments, changes to one part of the code base may break other code, which will become visible only when those pieces play together. The risk of this happening increases with every change made. As developers do multiple things sequentially, the effort of locating the root cause of an issue becomes increasingly difficult to uncover with passing time, and every change ("fix") to an unstable codebase will amplify the problem.
Dead giveaway? Developers call things "Done", and there's no Working Build for it yet.
Code SmellsYou don't need to be a developer to discover "code smells" which will eventually become a problem.
Some of the most obvious code smells are:
- "Mountain Ranges": The code, rotated 90 degrees left, looks a whole lot like a mountain range. Such code is too complex to be feasibly testable
- "Copy+Paste": Code that looks eerily similar multiple times over or developers who outright say that they develop by copy+pasting existing code segments, then modifying them, produce code that eventually becomes unsustainable.
- "The Gigabyte Class": A class that is unusually large will eventually become a problem. As a rule of thumb, a class with more than 5000 Lines of Code is probably fishy. YMMV.
- "Treasure Hunt": When you see developers moving across myriads of classes all the time to understand what's going on, there's probably a code structure issue.
There's tons more of code smells, but these are the most common to see when developers don't know how to create Clean Code.
Dead giveaway? Developers don't understand code produced by other team members.