TL;DR: Stage tests by cost and by what they can catch. Fast and deterministic on every commit (unit, lint, static analysis), selected integration and contract checks before merge, and larger environment or load suites after merge or on a schedule. Place tests by measured duration and failure risk; a security check can be fast and an end-to-end smoke test can belong in the merge gate.
How to approach it
Frame it as an allocation problem against a time budget, then place each test type by what it costs and what it uniquely catches. Name the latest safe point for discovering each failure, then place the corresponding check before that boundary.
A strong answer
The budget forces the shape. If the full environment suite exceeds ten minutes, decide which failures you are willing to find later, and how you limit the damage when you do.
On every commit, under five minutes. Linting and static analysis, unit tests, and dependency scanning. Measure each check: dependency scans can query a remote advisory database and some analyzers are expensive. Unit tests here must have no network and no database; the moment they need either classify them as integration tests and budget their setup time. Network use alone does not prove flakiness.
Before merge, under ten minutes total. Integration tests against real dependencies started as containers, plus a build of the artifact and a container image scan. This is where you catch contract mismatches, migration problems and configuration errors that unit tests structurally cannot see. Ephemeral dependencies per run, never a shared test database, because a shared one makes the suite order-dependent and intermittently red.
After deploy to staging, off the critical path. End-to-end tests through the real interface, contract tests against downstream services, and dynamic security scanning. Keep broad suites here when their measured runtime exceeds the feedback budget. Fast critical-path smoke and contract tests can still gate a merge; test type alone does not determine speed or reliability.
On a schedule. Performance and load tests, full dependency audits, chaos experiments. Use a nightly run for broad coverage if that detection delay is acceptable. A risky storage or authentication change may need its relevant performance or security check before release.
Two things that decide whether this survives contact with a team.
Flakiness is the real enemy of a test strategy. A test that fails randomly trains everyone to re-run, and once re-running is habit, a genuine failure gets re-run too. Track a flake rate per test, quarantine anything above a threshold so it reports without blocking, and give it an owner and a date. Quarantine removes blocking coverage. Provide a dependable replacement for high-risk behavior or record a temporary risk decision; do not silently remove the only payment-integrity check.
Coverage is a diagnostic, not a target. Mandating 80 percent produces tests written to touch lines rather than to assert behaviour. Better signals are whether the last few production incidents would have been caught, and whether a deliberate mutation of the code makes something fail.
The release decision: at this budget you are choosing to find some classes of defect after merge. Bound that risk with release gates and tested recovery, which is why test strategy and deployment strategy are one decision rather than two. A canary can limit some exposure, but cannot justify deferring checks for irreversible corruption or undetectable security failures.
Worked allocation: preserve the release gate
Assume a fictional checkout service has two minutes of setup, three minutes of unit checks and a four-minute database integration suite. Running those suites concurrently after setup takes about six minutes before runner and reporting overhead. A twelve-minute browser suite cannot fit that merge budget, but its payment-confirmation check still needs to pass before a candidate receives real traffic. Run that check against the built candidate in a release stage and hold promotion until it finishes.
Write the failure each test detects beside its placement. A unit check can reject an incorrect price calculation; a database test can demonstrate transaction rollback; a browser check can catch a missing confirmation page. None substitutes for the others merely because it is faster. If authentication changes, select the relevant expensive checks before release rather than waiting for the nightly schedule.
Try removing the idempotency guard in a local fixture. The duplicate-payment test should fail. If it stays green, investigate the assertion and test setup before using the suite as release evidence. Record the exact artifact that passed; a later rebuild would need its own evidence.
What interviewers probe next
"What do you do when the suite is already thirty minutes?" Measure per-test duration, parallelise by recorded time rather than file count, and move the slowest environment-dependent tests off the commit path. Repair or replace unreliable coverage before retiring it, with an explicit risk decision for any gap.
"How do you test infrastructure code?" Static analysis and policy checks on the plan, then apply into an ephemeral environment and assert on the result. A Terraform plan that a human reads is not a test.
"What is a contract test?" A test that the provider's response satisfies a consumer's expectation, run against both sides independently. It checks a defined interaction contract; it does not establish network routing, runtime configuration or complete user-journey correctness.
Common mistakes
Reciting the test pyramid with no reference to the time budget the question gave you.
Treating flaky tests as a discipline problem rather than as the thing destroying the gate.
Gating on coverage percentage, which reliably produces tests that assert nothing.