We all know testing is important
...so why isn’t it happening?
There are plenty of “reasons” not to test:
- “We don’t have time to write tests!”
- “Where do we even start with testing?”
- “Testing slows us down!”
- “Tests are too hard to maintain!”
- “Junior devs don’t know how to write tests...”
- “...and we don’t have bandwidth to train them.”
Hard or not, we need to write tests
If our code isn’t tested, we’re just guessing
Even smaller codebases have lots of edge cases
Manual quality assurance doesn’t catch everything
Testing Doesn’t Have to Be Hard
A battle-tested strategy
- Code changes must be sent as pull requests
- A build pipeline runs tests automatically
- The new code must meet testing requirements
- The new code must meet quality guidelines
- Change must be peer reviewed and approved
What should the testing requirements be?
- The app builds successfully
- All tests pass
- Coverage thresholds must be met for new code
- Coverage thresholds for the whole repo (maybe)
What should the quality guidelines be?
- Limit cyclomatic and cognitive complexity
- Avoid known problematic patterns
- Check for security vulnerabilities
- Eliminate duplicate code
We should not fail a pull request on style
Just use Prettier and forget about it.
Test and quality checks can be automated:
- Linters and IDE plugins to help as code is written
- Husky and Git hooks to check changes pre-push
- TravisCI and Jenkins to build and test PRs
- SonarCloud, Code Climate, Codacy for quality checks
- Prettier to auto-fix code style
Pull requests create a control flow
- No force pushing
- Creates a place for automated tests to run
- Requires team participation
Automated tests catch more edge cases before regressions happen
Quality checks minimize technical debt and maintenance overhead
Automating enforcement removes the need for a human code cop
Peer reviews create opportunities to learn
& share knowledge
Testable code is better code
- Cleaner separation of different functionality
- Fewer side effects (because mocking sucks)
- Better APIs because edge cases are tested for
Make the Right Thing the Easy Thing
Use built-in coaching to improve quality
Source: Codacy
Make the learning curve as shallow as possible
Using 3 packages for testing is confusing
A unified API makes testing approachable
Keeping tested code tested is significantly less hard
Internal training is key
- Hackathons to add tests to older code
- Hands-on workshops to teach testing techniques
- Cross-team code reviews to share knowledge
- Compile best practices into internal docs
- Coach the team on writing more testable code
- Hire external trainers if necessary
Don’t forget: executives also need training
- An untested product is fragile
- Fragile products break in unpredictable ways
- Unpredictability causes delays
- Delays cost money and frustrate customers
Make code quality a point of pride
Visually represent code health in public
Source: SonarQube
Measure code health over time for teams
Source: SonarQube
Make testing a deliverable not a “nice to have”
New features without tests are not safe to launch
What if people fight testing?
Change is hard:
- Old habits are hard to break
- New requirements cause anxiety
Replace old habits with better ones
Try to understand where resistance is coming from
Focus on the bright spots
Reward the right behavior
- Use testing and quality as a metric during reviews
- Publicly recognize team members who improve code
Reorganize resistant teams
Measure management on their team’s code quality
A word of caution:
Don’t add requirements without adjusting expectations. Deadlines will need to shift at first.
Stop rewarding bad behavior
Teams shipping features without tests missed their deadline
This is not okay:
“We just need to get something out there. We’ll add tests later.”
Be reasonable
Start plugging leaks first
Create a ramp-up period
Improving foundational quality will help to:
- Increase the reliability of code
- Decrease the time to find and fix bugs
- Speed up delivery times for new features
- Eliminate existing technical debt...
- ...and help prevent new debt from being created
- Lower the cost of maintenance
To create quality-driven culture in your company:
- Make the Right Thing the Easy Thing
- Provide support and ramp-up time for developers
- Convince management to make time for quality
- Reward the desired behavior...
- ...and stop rewarding bad behavior
- Automate as much of the process as possible
- Take pride in shipping quality, not just shipping
Testing is a supercharger for companies
It’s slow and difficult to get the mindset in place...
but then it’s unstoppable