37Left-Shift & Right-Shift Testing
What you will master here
- What shift-left and shift-right actually mean
- Practices that pull testing left (TDD, contract tests, pre-commit checks)
- Practices that extend testing right (synthetic monitoring, chaos, observability)
- Where SDET adds the most leverage at each end
37.1 The two halves
Figure 16 — Shift-left finds bugs earlier; shift-right catches what slips through.
37.2 Shift-left practices
| Practice | What it is | SDET role |
|---|---|---|
| 3 amigos | PM, dev, tester refine each story together before code | Surface edge cases, define test data needs |
| Example mapping / BDD | Write acceptance criteria as concrete examples | Drive the conversation; convert examples to tests |
| TDD / dev-written unit tests | Tests before code, owned by devs | Coach, review, ensure quality of unit tests |
| Pre-commit hooks | Lint, type-check, fast tests before push | Maintain hook config; add fast checks |
| Contract testing (Pact) | Producer + consumer agree on API shape; test contract independently | Champion the practice; own broker |
| Static analysis / linting | ESLint, SonarQube, type checkers | Configure rules; gate PRs |
| Threat modelling | Find security weaknesses in design phase | Inject security-aware test cases |
| PR-level tests | Smoke + targeted regression on every PR | Build the pipeline |
37.3 Shift-right practices
| Practice | What it is | SDET role |
|---|---|---|
| Synthetic monitoring | Scheduled Playwright/REST checks against prod | Author and own these "always-on" tests |
| Canary release / feature flags | Roll out to 1% before 100%; auto-rollback on errors | Define gating metrics; partner with SRE |
| A/B testing | Compare two variants on real traffic | Verify the experiment instrumentation works |
| Chaos engineering | Inject failures (latency, kill pods) to test resilience | Author chaos experiments and verify auto-recovery |
| Observability (logs, traces, metrics) | See what prod is actually doing | Define SLIs / SLOs; alert on drift |
| Bug bash in prod-like environments | Team-wide exploratory testing of a build | Organise, capture findings |
| User feedback loops | In-app feedback, support ticket aggregation | Convert recurring issues into tests |
37.4 Synthetic monitoring with Playwright
// tests/prod-smoke.spec.ts — runs every 5 minutes in production
test('prod login still works', async ({ page }) => {
await page.goto('https://app.acme.com/login');
await page.getByLabel('Email').fill(process.env.SYNTH_USER!);
await page.getByLabel('Password').fill(process.env.SYNTH_PASS!);
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByText('Dashboard')).toBeVisible({ timeout: 10_000 });
});
test('prod checkout API is up', async ({ request }) => {
const r = await request.get('https://api.acme.com/health');
expect(r.status()).toBe(200);
});
Schedule via GitHub Actions cron, Datadog Synthetics, or Checkly. Page the on-call if a check fails twice in a row.
37.5 Contract testing with Pact (1-min mental model)
- Consumer (frontend) defines what it expects from the API.
- Consumer's tests use a mock that records the expectation as a "Pact" file.
- Pact file is published to a broker.
- Producer (API) replays the contract in its own tests — must match.
- If producer changes break the contract, producer's CI fails before deploy.
Result: frontend and backend evolve independently without integration surprises. Common in microservice orgs.
37.6 Feature flags + canaries
// Flag in code
if (await featureFlags.isEnabled('new-checkout')) {
return <NewCheckout />;
} else {
return <OldCheckout />;
}
// SDET checks both paths in CI
test('old checkout', async ({ page }) => {
await page.context().addCookies([{ name: 'ff-new-checkout', value: 'off', url: '/' }]);
/* ...assert old flow... */
});
test('new checkout', async ({ page }) => {
await page.context().addCookies([{ name: 'ff-new-checkout', value: 'on', url: '/' }]);
/* ...assert new flow... */
});
37.7 What "right-shift" looks like in practice
- You ship a feature behind a flag, off for everyone.
- Enable it for 1% of users.
- Monitor: error rate, conversion, latency on the 1%.
- If metrics OK, ramp to 10%, then 50%, then 100%.
- If error rate spikes, flag off — instant rollback without a deploy.
- SDET defines the "metrics-OK" thresholds and authors the dashboards.
Module 30 — Shift Q&A bank
What does "shift-left" mean?
Move quality activities earlier in the development cycle — into design, dev, and pre-commit phases — so defects are found and fixed when they're cheapest. Examples: TDD, contract tests, pre-commit lint, BDD/example mapping.
What does "shift-right" mean?
Extend quality activities into production — synthetic monitoring, canary releases, feature flags, chaos engineering, observability. Catch what slipped past pre-prod testing, with minimal blast radius via gradual rollout.
Are shift-left and shift-right competing or complementary?
Complementary. Shift-left makes the test net tight before deploy. Shift-right makes the safety net wide after deploy. Both serve the same goal: detect issues fast, minimise impact.
What's contract testing and when does it pay off?
Consumer and producer of an API agree on a contract; each tests against it independently. Frontend doesn't need a real backend to test against, and backend can't break the frontend without its CI failing. Pays off heavily in microservice / large-org setups where teams move independently.
What is synthetic monitoring?
Scheduled tests that hit production from outside (or from a known location) on a cadence, alerting on failures. Like a heartbeat for critical flows. Lighter and faster than full regression — usually a few critical user journeys + API health checks.
What's a feature flag?
A switch in code that gates new behaviour. Deploys the code but keeps it off until you flip the flag. Enables canary releases (% rollout), instant rollback (without redeploy), and runtime A/B testing. SDETs test both flag states.
How do you test feature-flagged code?
Run the test suite twice — once with the flag on, once with it off. In Playwright, set the flag-controlling cookie/local-storage in a fixture. Don't let the test depend on the global default; explicitly configure both states.
What is chaos engineering?
Intentionally inject failures (kill pods, drop network packets, raise latency) into a controlled environment and verify the system stays usable. SDETs may author chaos experiments and add tests that assert auto-recovery / graceful degradation.
What's an SLO and why does an SDET care?
Service Level Objective — a measurable reliability target (e.g. "99.9% of API requests < 200 ms"). SDETs help define test coverage that backs the SLO and alerts that watch it in production. SLOs translate "is this app good?" into objective numbers.
One-sentence pitch for shifting quality both ways.
"Find bugs as early as possible (shift-left); catch the ones that slip through with minimal blast radius (shift-right). Owning quality across the lifecycle, not just the QA phase, is the SDET's leverage."