By Arjun Mehta
Shift left testing is the idea that testing should move earlier in the development process. Instead of testing after code is written, test while it's being written. Find bugs when they're cheap to fix, not after they're in production.
Sounds good. It is good. But the phrase "shift left" has been used to justify everything from unit tests to chaos engineering, and most teams are doing it wrong.
Here's what actually matters.
What Shift Left Actually Means
Traditional waterfall process: Design → Code → Test → Deploy → Crisis Management
Shift left means moving testing earlier: Design → Code+Test → Deploy
That's it. That's the whole idea.
The goal is simple: catch bugs when it's cheap to fix. A bug caught during code review costs hours. The same bug caught in production costs thousands.
Why It Works
Bug costs scale exponentially:
- During development: 1 hour to fix
- During code review: 2-3 hours (context-switching)
- During QA: 4-8 hours (understanding the system, reproducing, fixing, re-testing)
- In production: 40+ hours (debugging, customer impact, hotfix, verification, root cause analysis)
Bug in code review is 3x the cost of bug during development. Bug in production is 40x.
If you can move testing left, you save money. Simple math.
The Three Types of Testing
Unit tests. Does this function work correctly in isolation? Catches logic errors. Fast to run. Should be automatic.
Integration tests. Do these systems work together? Catches assumption mismatches. Medium speed. Should be automated.
End-to-end tests. Does the whole system work? Catches unexpected interactions. Slow to run. Should be spot-check, not comprehensive.
Most teams get this backwards. They write extensive end-to-end tests and skip unit tests. End-to-end tests are slow, flaky, and expensive to maintain. They should be last resort, not primary defense.
Shift left means: write unit tests first. They're cheap and fast. Then integration tests for critical paths. Then end-to-end tests for critical workflows.
When Shift Left Doesn't Work
1. When you're writing the wrong tests. A team writing 10,000 end-to-end tests is not shifting left. They're writing expensive tests that take 6 hours to run. They're not testing earlier. They're testing slower.
2. When tests become busywork. Your QA team needs to test every click on every screen. They do. It takes forever. You achieve 0% automation benefit because tests are running constantly and nobody trusts them.
3. When you optimize for coverage instead of risk. You have 95% code coverage but you're still finding bugs in production. Coverage metrics are theater. Tests should target high-risk code, not maximize percentage.
4. When developers treat testing as separate from coding. If developers write code, then QA writes tests, you haven't shifted left. You've just moved QA earlier in the timeline. Real shift left: developers write tests while they're writing code.
How to Actually Do It
1. Start With Unit Tests
Unit tests are: fast, reliable, pinpoint failures, easy to write.
Every developer should write unit tests for their code. Not because some process says so. Because it makes their life easier. They catch their own bugs instead of waiting for QA.
Target: 70%+ coverage of business logic. Not 100% coverage of everything. Coverage of things that matter.
2. Add Integration Tests for Critical Paths
Once unit tests are solid, add integration tests for the scary stuff:
- Payment processing
- Authentication
- Data consistency
- External API calls
These tests take longer but catch assumption mismatches between systems.
3. Use End-to-End Tests as Smoke Tests
End-to-end tests are expensive. Use them to verify the critical path works. "User can sign up, log in, and check out." That's the test. Not "every button on every page works."
4. Make Tests Run in the Development Loop
If tests run after code is committed, they're not shifting left. They're just validating what's already shipped.
Real shift left: developers run tests locally before committing. Tests run automatically on PR. Feedback is instant.
If your test suite takes 30 minutes to run, developers won't run it locally. You've failed at shift left.
5. Kill Tests That Don't Catch Bugs
Testimony: A team has 5,000 tests. They take 2 hours to run. They find zero bugs in production (bugs slip through anyway). The tests are theater.
Better: 500 tests that run in 5 minutes and catch 95% of bugs. Those are useful tests.
Kill tests that don't fail when code is broken. They're just noise.
The Real Payoff
When shift left is working:
- Developers catch their own bugs instantly (faster feedback)
- Code review is higher quality (reviewer looks at logic, not hunting bugs)
- QA finds edge cases, not obvious failures (better use of QA time)
- Production incidents decrease (fewer bugs escape)
- Refactoring becomes safe (tests give confidence)
All of this frees capacity. You're not spending 40% of time firefighting production bugs.
Why This Matters for Engineering Leaders
Your team's velocity is constrained by how many bugs slip to production. Every production bug costs: diagnosis, hotfix, verification, on-call response, customer impact.
That's all capacity that could go to features.
Shift left means moving testing earlier, which means bugs don't exist in production, which means more capacity for features.
It's not about testing philosophy. It's about team efficiency.
With Glue
When you can't see your codebase, you don't know which parts are risky. With Glue, you can identify high-complexity code and high-risk systems. Those are the places that need testing.
Testing the wrong stuff is waste. Glue helps you target testing where it matters.
Frequently Asked Questions
How much testing is enough? Enough that you're shipping with confidence. If you're nervous about deploying, you don't have enough tests. If you're spending more time writing tests than shipping features, you have too many.
Should QA teams disappear? No. Shift left is about catching bugs early, not eliminating quality assurance. QA teams shift to: exploratory testing, edge case discovery, usability validation, performance testing. Not automation of every click.
How do we handle legacy code with no tests? Start with critical paths. Write tests for the stuff that breaks most frequently. Don't try to test everything retroactively. That's too expensive. Invest in new code being well-tested.