![]() |
VOOZH | about |
We’re so glad you’re here. You can expect all the best TNS content to arrive Monday through Friday to keep you on top of the news and at the top of your game.
Check your inbox for a confirmation email where you can adjust your preferences and even join additional groups.
Follow TNS on your favorite social media networks.
Become a TNS follower on LinkedIn.
Check out the latest featured and trending stories while you wait for your first TNS newsletter.
This is the first of two parts. Read Part 2.
Shift left testing is the practice of moving testing earlier in the development process. In a traditional development cycle, testing often occurs after the completion of a feature or even at the end of the development phase. Shift left testing challenges this by integrating testing activities from the beginning and throughout the development process.
Let’s start by discussing why we chose the option to shift left, as it’s not the only way to solve scaling problems with your software development life cycle (SDLC).
Before we decide to move more testing over to the development side of the process, let’s discuss why leaders would make this decision in the first place.
There’s a cynical read of “shift left” that is “make people do more work but pay them the same.” A stressed-out dev team might rebel at the thought of adding more concerns to their docket. But the real motivation for shifting testing left is a frustration with a software release cycle in deadlock, developers forced to context switch and never allowed to get into a flow state and a glacial development velocity.
Imagine you’re at a company that’s scaling up past the startup stage. You all remember a time when features went out in weeks or even days, but those days are long gone. Now multiple teams are trying to release branches at the same time, and QA is stressed trying to find problems before they release to production.
Worse, the complexity of the microservice architecture means that developers can’t effectively do integration tests before shipping code off for QA. There’s a lot of talk about improving contract testing, but again, things are scaling quickly and the estimates for writing clear intra-service contracts and refactoring to match would take months. In the meantime, developers are stuck writing unit tests and creating crude mocks for outside services like payment providers and even the services of other teams. This leads to more surprises when code is deployed to pre-release environments like staging.
So our engineering leaders are faced with a choice: How to improve developer velocity while also shipping fewer bugs to production? You have two options:
This isn’t a terribly scalable choice. Already teams are occasionally conflicting over who gets to deploy to staging, and how long they need to have the environment reserved. Further, even with more QA engineers, you’re still making developers write code, run limited tests, push and then wait for a human being to write back with what problems were detected. The result is an “outer loop” feedback cycle where devs either have to pause all work until they get QA feedback or context switch between two branches as they try to work on the next feature while switching back and finding problems with the last thing they pushed. Even with an unlimited budget for the QA team, this definitely won’t scale to hundreds of developers.
QA has a major role in the strategic vision and architecture decisions for testing as an engineering team shifts testing left. But the quest to ensure that more releases are successful isn’t perfectly served by just expanding the QA team. Why is that?
Is that list of attributes an array or an object? And is that locator 0-indexed or not? These small integration errors can block a release when QA is testing them. Instead of a developer finding small problems with their own code and quickly fixing the errors, QA is now required to document and communicate back the issue. Even worse is when QA doesn’t know who to communicate with:
As a developer you make updates to `user_state_controller`, but as a QA you may be testing things like “user is able to update their login.” This isn’t a mismatch, as the teams have different goals. But when QA finds errors in a user flow, they don’t necessarily know who in development would be the best person to talk to. This causes further delays.
Without a team of engineers to determine the best set of tests to run, QA ends up running tests at a reduced cadence and only finding problems in large groups.
This is a basic breakdown that I think warrants more discussion: Running a large test suite by a QA team is an appealing way to make sure that everything is working as designed end to end. But high-fidelity tests also need to be high frequency. If not, we lose the basic benefits of source control: Without tests running for every single commit, we lose easy rollbacks and fixes. This is one of many ways that “shift left” testing is a return to an older standard: Developers should be able to tell right away if their current group of changes broke something. Relying on QA to find problems the first time means you’re picking through a long list of failures trying to determine which were caused by which commit.
Again, we’re talking about a regression from the coding and delivery standards of 2005. The waterfall model makes it impossible to do true continuous delivery to production.
One essential idea here is that QA being the only finders of bugs is disempowering to your engineers.
Even without the leadership-level concerns about the impact to velocity, you can imagine that a setup where most feedback comes on the outer loop can be frustrating and painful for engineers. My own ego aside, I don’t want to push code that I have little confidence in. This brings us to option two:
In this scenario, breaking things as a developer can feel fun again: We’re experimenting, seeing what the other services can support and only pushing what we know works. QA still has a major role in this design, but their role is less in manually testing and finding individual bugs. Rather, the QA team becomes a strategic leader in defining automation strategy, selecting testing frameworks and enabling developers to have more confidence in their code. With testing available to every engineer every day, there will be many more tests being written and run, but their feedback goes straight to developers on an inner loop of feedback.
In a recent discussion in a platform engineering lean coffee group, one idea stuck with me, mentioned by a few participants:
“Microservices present a lot of advantages, but microservices are much more difficult to test. This problem is so severe that many teams don’t see real benefit from microservices.”
I’ve written about this before but to summarize: In the era of monoliths, there was often a way to run the whole system, or a facsimile, on your laptop with minimal friction. This meant significant testing could happen right as you were developing.
So really, when we talk about shifting testing left, we’re talking about shifting it back. We still have a role for QA teams, but we want to put the first rounds of testing back in the hands of the engineers writing the feature.
In a follow-up to this article, I’ll write about the role that QA has and will continue to have as you shift the responsibility for running testing over to your development teams. In short, QA still has a major role to play and will be doing a lot more, not less, when developers are running more of your tests. If you’d like to discuss this article and the ideas of shift left testing, join us in the Signadot Slack. We’d love to hear your ideas!