Interview prep · 227 questions

SDET interview questions

Updated

Architecture, system design for test, and the coding round. These are the questions that decide whether you are hired as an SDET or as an automation engineer with a different title.

70 questions

What's the difference between a QA engineer and an SDET?

Role & Scopejuniormid

A QA engineer owns the quality judgment: what to test, what risk we're carrying, whether this release is safe.

A QA engineer owns the quality judgment: what to test, what risk we're carrying, whether this release is safe. An SDET owns that plus the engineering that proves it: the framework, test infrastructure, CI pipeline, test data systems — production-grade code, reviewed by developers as a peer.

Both test. One is also accountable for the code that tests.

Real-world example

Same Tuesday, two roles: the QA engineer notices the payment story doesn't define what happens when the card fails mid-renewal — and asks. The SDET gets asked why the suite takes 40 minutes, finds tests sharing one seeded account, rebuilds the data layer parallel-safe and shards the run to 8 minutes. Different problems, both quality.

Key points
  • QA: the quality call
  • SDET: + the engineering behind it
  • SDET code faces dev review
They'll ask next · tap one for the answer
The trap

'SDET = QA who codes' — it's ownership of test systems, not a scripting badge.

Copy link

Explain the test pyramid. What happens when it's inverted?

Test Architecturejuniormidsenior

Many fast unit tests at the base, fewer API/integration tests in the middle, few E2E/UI tests on top — because cost, speed and flakiness all rise as you go up.

Many fast unit tests at the base, fewer API/integration tests in the middle, few E2E/UI tests on top — because cost, speed and flakiness all rise as you go up.

Inverted (the 'ice cream cone'): hundreds of UI tests, thin API, few units — slow pipelines, flaky reds, failures that point nowhere, and a team that stops trusting green. The fix is moving checks down, not adding hardware.

Real-world example

Inherited an inverted suite: 600 UI tests, 90 minutes, red twice a week for non-bugs. A quarter of the UI tests were re-checking pricing rules the API could verify in milliseconds. Six months of moving checks down: 150 UI journeys, 800 API checks, 12-minute pipeline — and green meant something again.

Key points
  • Unit many, API middle, UI few
  • Up = slower, costlier, flakier
  • Inverted = slow flaky mistrust
They'll ask next · tap one for the answer
The trap

Drawing the triangle without the consequence — the question is really about the inverted case and its bill.

Copy link

Design a test automation framework from scratch. Walk me through your architecture.

Test Architecturesenior

Layered, bottom-up: config (per-environment, secrets injected); drivers/clients (browser factory, API client); pages/components for UI structure; data layer (builders/factories, API-seeded,…

Layered, bottom-up: config (per-environment, secrets injected); drivers/clients (browser factory, API client); pages/components for UI structure; data layer (builders/factories, API-seeded, parallel-safe); tests — thin scenarios only; reporting (artifacts on failure, CI-published). Auth handled once, below the UI.

Then defend the choices: composition over inheritance, API-first setup, isolation over shared state — and what you deliberately left out.

Real-world example

The choice interviewers always probe from mine: no BaseTest god-class. Fixtures compose — a test needing only an API client never pays for a browser. Second probe: auth is an API call injecting session state per worker; the UI login is one dedicated test, not a 200-test tax.

Key points
  • Config → clients → pages → data → tests → reporting
  • Thin tests, auth below UI
  • Defend the trade-offs
They'll ask next · tap one for the answer
The trap

Naming tools instead of layers — 'Playwright, pytest, Allure' is a stack, not an architecture.

Copy link

How would you design a test strategy for a microservices architecture?

System Design for Testsenior

Push confidence down and decouple teams: strong unit + service tests per service in isolation (dependencies mocked); contract tests between every consumer-provider pair — the layer that replaces most…

Push confidence down and decouple teams: strong unit + service tests per service in isolation (dependencies mocked); contract tests between every consumer-provider pair — the layer that replaces most cross-service E2E; a thin critical-journey E2E set on a full environment; and shift-right — canaries, monitoring, alerting as part of the strategy, because integration truth lives in production.

The anti-goal: a giant staging where all services must be green to test anything.

Real-world example

Twelve services, and the old approach — full-stack E2E for every feature — meant any team's bug blocked everyone's pipeline. The redesign: Pact contracts on all pairs, service tests against mocks, and E2E cut to eight money journeys. Deploy independence returned; the 'staging is broken again' channel went quiet.

Key points
  • Service tests isolated, mocked deps
  • Contracts replace most E2E
  • Thin journeys + production signals
They'll ask next · tap one for the answer
The trap

Proposing to E2E-test every service interaction — the exact strategy microservices make impossible.

Copy link

Design a test data management system.

System Design for Testsenior

Three capabilities: creation — factories/builders making entities on demand via API or direct seeding ('a user with an expired card' as one call); isolation — unique-per-run data, parallel-safe, torn…

Three capabilities: creation — factories/builders making entities on demand via API or direct seeding ('a user with an expired card' as one call); isolation — unique-per-run data, parallel-safe, torn down or namespaced; realistic bulk — anonymised production-shaped datasets for volume, migration and performance work, refreshed on schedule.

Rule one: functional tests never share mutable data. Rule two: production data never enters test systems un-anonymised.

Real-world example

The system that ended our Monday flakes: a data API in the test env — POST /test-data/users with traits, backed by factories, auto-tagged by run-id, swept nightly. Any test, any worker, fresh data in ~200ms. The old shared 'golden accounts' spreadsheet was deleted with ceremony.

Key points
  • Factories on demand, via API
  • Unique per run, swept after
  • Anonymised bulk for scale work
They'll ask next · tap one for the answer
The trap

'A shared seeded database' — the design whose flakes this question was written to expose.

Copy link

Design a system to run 10,000 tests in under 10 minutes.

System Design for Testsenior

Parallelism plus honesty about the mix. The math out loud: if the average test is 3s, that's 30,000s of work — ~50 workers for 10 minutes.

Parallelism plus honesty about the mix. The math out loud: if the average test is 3s, that's 30,000s of work — ~50 workers for 10 minutes. So: shard across workers (containers, ephemeral), balance shards by duration not count, make every test isolation-safe first, split by layer (units in seconds stay local; the UI slice gets the workers), cache builds/deps, and fail fast with live results.

The unlock is never hardware alone — it's tests that can run anywhere, in any order.

Real-world example

The real bottleneck when we did this wasn't compute — it was 200 tests pinned to one shared staging database. Fixed data isolation first (namespaced per worker), then sharding actually worked: 42 containers, duration-balanced from timing history, 10k tests in 8:40. The naive count-based split had one shard finishing 6 minutes late every run.

Key points
  • Do the worker math aloud
  • Isolation before parallelism
  • Balance shards by duration
They'll ask next · tap one for the answer
The trap

'Add more machines' without isolation math — 10k entangled tests on 50 workers is 50 ways to collide.

Copy link

Design a test reporting and analytics dashboard. What would you track?

System Design for Testsenior

Two audiences, two views. Engineers, per run: failures with artifacts inline (trace, screenshot, logs), new-vs-known failure, duration, flake markers, build/commit under test.

Two audiences, two views. Engineers, per run: failures with artifacts inline (trace, screenshot, logs), new-vs-known failure, duration, flake markers, build/commit under test. Leads, over time: pass-rate and flake-rate trends, suite duration creep, slowest tests, quarantine count and age, escaped-defect correlation.

Every widget must answer a question someone actually asks — dashboards die of decoration.

Real-world example

The single most-used view we built wasn't the pass-rate chart — it was 'what's newly failing on THIS commit vs yesterday': it turned triage from reading 40 reds into reading 3. Second most-used: the flake leaderboard, because shame is a surprisingly effective maintenance strategy.

Key points
  • Per-run: artifacts + new-vs-known
  • Trends: flake, duration, quarantine age
  • Every widget answers a question
They'll ask next · tap one for the answer
The trap

A pass-rate pie chart as the centrepiece — pretty, and it answers no question anyone asks during triage.

Copy link

How would you test a URL shortener?

System Design for Testmidsenior

Structure it aloud. Functional: shorten → redirect round-trip, custom aliases, duplicates, invalid/malicious URLs. Edge: unicode URLs, huge URLs, expired links, collision behaviour at scale.

Structure it aloud. Functional: shorten → redirect round-trip, custom aliases, duplicates, invalid/malicious URLs. Edge: unicode URLs, huge URLs, expired links, collision behaviour at scale. Non-functional: redirect latency (this IS the product), read-heavy load (reads dwarf writes), availability. Security: open-redirect abuse, enumeration of short codes, rate limits, javascript: scheme injection.

Close with prioritisation: correctness of redirect and its latency first — that's the product's one job.

Real-world example

The two findings that impress in this design: short codes being sequential (enumerate everyone's links — privacy leak), and the service happily shortening javascript:alert(1) (stored XSS via redirect). Both are 'design the tests' answers that show security thinking without being asked.

Key points
  • Round-trip + collisions + expiry
  • Read-heavy load, redirect latency
  • Enumeration + scheme injection
They'll ask next · tap one for the answer
The trap

Diving into shorten/redirect happy path and stopping — the question is scored on structure and the non-functional half.

Copy link

What is contract testing, and when is it worth the investment?

API & Contract Testingsenior

Verifying that a consumer's expectations of a provider's API match what the provider actually serves — as executable contracts (Pact-style), checked in BOTH pipelines before deploy.

Verifying that a consumer's expectations of a provider's API match what the provider actually serves — as executable contracts (Pact-style), checked in BOTH pipelines before deploy. Consumer records what it needs; provider replays and proves it still holds.

Worth it when independent teams deploy services that talk to each other — it's the layer that catches breaking changes without a shared staging. Overkill for a monolith or when one team owns both sides.

Real-world example

The incident that sold it here: orders team renamed customerId to customer_id, integration environment was green (stale deploy), production broke at 9am. With Pact, the provider build would have failed the moment the change contradicted the orders-consumer contract — three days before deploy, in their own CI.

Key points
  • Consumer expectations, provider-verified
  • Runs pre-deploy, both pipelines
  • For independent teams/services
They'll ask next · tap one for the answer
The trap

'Schema validation' as the definition — contracts are about a specific consumer's expectations, which is why they catch what generic schemas miss.

Copy link

What would you test in an API, and how would you prioritise?

API & Contract Testingmidsenior

The full checklist: status codes, response body and schema, errors with useful messages, authz (the other user's ID → 403), side effects persisted, idempotency, headers, latency.

The full checklist: status codes, response body and schema, errors with useful messages, authz (the other user's ID → 403), side effects persisted, idempotency, headers, latency.

Prioritised: 1) happy-path contract per endpoint — the smoke; 2) auth/authz everywhere — cheapest catastrophic bugs; 3) error paths consumers depend on; 4) edge data and idempotency; 5) performance baselines. Money and permissions before completeness.

Real-world example

Priority 2 earning its rank: GET /orders/{id} with the wrong user's token returned the order — an IDOR leaking purchase history, found in the first hour of authz-first testing. Textbook-perfect responses everywhere else; the checklist order exists because of exactly this class of bug.

Key points
  • Body+schema, authz, side effects, idempotency
  • Auth checks on EVERY endpoint
  • Money + permissions first
They'll ask next · tap one for the answer
The trap

A flat unprioritised list — the question has 'prioritise' in it because triage judgment is what's being hired.

Copy link

How do you test JWT or OAuth2 authentication?

API & Contract Testingmidsenior

JWT: expired token → 401, tampered payload/signature → rejected, alg:none attack rejected, right claims enforced (roles, audience, issuer), expiry actually honoured server-side.

JWT: expired token → 401, tampered payload/signature → rejected, alg:none attack rejected, right claims enforced (roles, audience, issuer), expiry actually honoured server-side.

OAuth2: full grant flow, refresh rotation, scope enforcement (token with read scope can't write), revocation actually revokes, redirect_uri strictly validated (the classic hole), state parameter enforced (CSRF).

Theme: don't test that login works — test that everything ELSE is rejected.

Real-world example

The finds that recur: decode the JWT at jwt.io, flip role:user to role:admin, re-send without re-signing — rejected properly. But 'logout' only cleared the cookie: the old token kept working for its full 24h TTL against the API directly. Session revocation was client-side theatre. That's a real vulnerability from a ten-minute test.

Key points
  • Tampered/expired/none-alg → reject
  • Scopes, audience, revocation real
  • redirect_uri + state validation
They'll ask next · tap one for the answer
The trap

'I test valid and invalid login' — auth testing is about forged, expired, replayed and over-scoped, not wrong passwords.

Copy link

What is idempotency, and why does it matter for testing?

API & Contract Testingmidsenior

An operation is idempotent if doing it twice has the same effect as once — GET/PUT/DELETE by design, POST only if engineered (idempotency keys).

An operation is idempotent if doing it twice has the same effect as once — GET/PUT/DELETE by design, POST only if engineered (idempotency keys).

Why testers care: retries are everywhere — networks fail, users double-click, queues redeliver. Every retry against a non-idempotent operation is a potential double-charge, double-email, duplicate order. The test: same request twice (then concurrently), assert exactly one effect.

Real-world example

The double-click that cost real money: payment POST, slow network, user clicks twice, two charges — no idempotency key on the endpoint. The fix (client-generated key, server dedupe) came with a test that fires the same key concurrently and asserts one charge. That test has failed twice since — both times before production.

Key points
  • Twice = once, effect-wise
  • Retries/double-clicks are normal traffic
  • Test: duplicate + concurrent duplicate
They'll ask next · tap one for the answer
The trap

Defining it without the retry story — 'networks retry, so non-idempotent writes are latent double-charges' IS the answer.

Copy link

Explain the difference between a mock, a stub, a spy and a fake.

Mocking & Test Doublesmidsenior

All test doubles, different jobs. Stub: returns canned answers — you assert on your system's state. Mock: pre-programmed with expectations — the assertion IS the interaction ('was charge() called…

All test doubles, different jobs. Stub: returns canned answers — you assert on your system's state. Mock: pre-programmed with expectations — the assertion IS the interaction ('was charge() called once with $50'). Spy: real thing (or stub) that records calls for later inspection. Fake: working lightweight implementation — in-memory DB, fake payment gateway.

Rule of thumb: stub queries, mock commands, fake infrastructure.

Real-world example

One checkout test, all four: stub the tax service (canned 8%), mock the email sender (assert exactly one receipt sent), spy on the metrics client (record what was emitted, assert later), fake the database (in-memory repo so the test runs in 50ms). Naming which and why is the senior version of the answer.

Key points
  • Stub answers, mock expects
  • Spy records, fake implements
  • Stub queries, mock commands
They'll ask next · tap one for the answer
The trap

Using 'mock' for all four — this question exists precisely to catch that.

Copy link

When should you mock a dependency, and when should you use the real thing?

Mocking & Test Doublessenior

Mock what you don't control or can't afford: third-party APIs, slow/flaky externals, error conditions you can't trigger on demand, anything billing per call.

Mock what you don't control or can't afford: third-party APIs, slow/flaky externals, error conditions you can't trigger on demand, anything billing per call. Use the real thing for what the test exists to verify: your logic, your queries, your integration seams — with containers making 'real but disposable' cheap.

Every mock is a small lie about the world; keep an integration check somewhere that tells the truth.

Real-world example

We mocked the payment provider everywhere — clean, fast, green. Their sandbox meanwhile changed a decline code, and production handled it wrong: our mocks were unanimously testing yesterday's reality. The fix wasn't unmocking — it was one scheduled contract check against the sandbox whose job is catching drift.

Key points
  • Mock: uncontrolled, slow, costly, error paths
  • Real: your logic and seams
  • Mocks drift — pin with contract checks
They'll ask next · tap one for the answer
The trap

'Mock everything for speed' — fast tests that verify a puppet show while integration bugs walk through.

Copy link

What is service virtualisation and how does it differ from mocking?

Mocking & Test Doublessenior

A running simulated service — WireMock/Mountebank/Hoverfly serving a dependency's API over the network: stateful if needed, latency-injectable, shared by any consumer regardless of language.

A running simulated service — WireMock/Mountebank/Hoverfly serving a dependency's API over the network: stateful if needed, latency-injectable, shared by any consumer regardless of language. Mocking lives inside your test process and dies with it.

Virtualise when: many teams need the same simulated dependency, you're testing deployed apps (not just code), or you need fault/latency injection at the wire level.

Real-world example

The mainframe our app depended on had a two-week wait for test slots. A WireMock virtual double — recorded from real traffic, wired into every lower environment — meant twelve teams tested daily against 'the mainframe', including its documented 30s timeout mode, which nobody had ever dared trigger on the real one.

Key points
  • Runs on the network, stateful, shared
  • Mocks: in-process, per-test
  • Wire-level latency/fault injection
They'll ask next · tap one for the answer
The trap

Treating it as 'big mocking' — the network boundary, statefulness and shared use are the actual differences.

Copy link

Explain load, stress, soak and spike testing.

Performance Testingmidsenior

Load: expected traffic — does it meet SLAs at normal and peak? Stress: beyond capacity — where does it break, and does it break gracefully?

Load: expected traffic — does it meet SLAs at normal and peak? Stress: beyond capacity — where does it break, and does it break gracefully? Soak: normal load for hours/days — leaks, connection exhaustion, slow rot. Spike: sudden surge — flash sale, push notification — and the recovery after.

Each answers a different business question; naming which question is the senior part.

Real-world example

Same system, four verdicts: load fine at 2× normal; stress found the DB pool exhausting at 5× with cascading timeouts (not graceful); soak found a 40MB/hour leak that OOM-killed the service every ~3 days — explaining the 'random' weekend restarts; spike showed 90s of errors after a push notification while autoscaling woke up.

Key points
  • Load=SLA, stress=breaking point
  • Soak=leaks over time
  • Spike=surge + recovery
They'll ask next · tap one for the answer
The trap

Definitions without the business question each answers — 'soak finds leaks' beats 'soak is long-duration testing'.

Copy link

Why is average response time a misleading metric? What should you use instead?

Performance Testingmidsenior

Averages hide the suffering: one thousand 100ms requests plus ten 10-second ones average ~200ms — looks fine, ten users had a terrible time. Latency is skewed, so the mean tracks the lucky majority.

Averages hide the suffering: one thousand 100ms requests plus ten 10-second ones average ~200ms — looks fine, ten users had a terrible time. Latency is skewed, so the mean tracks the lucky majority.

Use percentiles: p50 (typical), p95/p99 (the tail — your unluckiest real users), plus error rate and throughput together. SLOs are written in percentiles for exactly this reason.

Real-world example

Dashboard said avg 180ms, support said 'checkout is slow'. p99 told the truth: 8 seconds — every ~100th request hit a cold cache path. Fixing it moved the average barely at all and killed the complaints entirely. The average was measuring the happy crowd; the tail was where the users lived.

Key points
  • Means hide the tail
  • p95/p99 = real user pain
  • Percentiles + error rate together
They'll ask next · tap one for the answer
The trap

Knowing 'use percentiles' without the arithmetic story of WHY the mean lies — the example is the answer.

Copy link

A load test shows response times degrading. How do you find the bottleneck?

Performance Testingsenior

Follow the request through layers, measuring at each: load balancer → app (CPU? threads? GC?) → connection pools (exhausted?) → database (slow queries, locks, missing indexes) → external calls →…

Follow the request through layers, measuring at each: load balancer → app (CPU? threads? GC?) → connection pools (exhausted?) → database (slow queries, locks, missing indexes) → external calls → infrastructure (network, disk).

Correlate WHEN degradation starts with WHAT saturates at that moment — dashboards or APM traces make it minutes. The bottleneck is whatever hits its ceiling first; fix it and re-run, because there's always a next one.

Real-world example

Degradation at ~300 users: app CPU 40%, DB CPU 30% — nothing obviously hot. The connection pool graph told it: maxed at 50, requests queueing for a connection. Pool raised, re-run — now the DB was the wall at 700 users via one unindexed query the profiler named. Two bottlenecks, one afternoon, zero guessing.

Key points
  • Layer by layer, with numbers
  • Correlate onset with saturation
  • Fix, re-run — next ceiling appears
They'll ask next · tap one for the answer
The trap

'Check the database' as a reflex — sometimes right, but the method is layered measurement, not a favourite suspect.

Copy link

Why would you containerise your test environment?

Containers & Infrastructuremidsenior

Determinism and disposability: the same pinned image runs on every laptop and CI worker — 'works on my machine' dies; environments spin up per run and vanish, so no drift, no shared-state rot, and…

Determinism and disposability: the same pinned image runs on every laptop and CI worker — 'works on my machine' dies; environments spin up per run and vanish, so no drift, no shared-state rot, and parallelism gets one clean stack per worker.

Testcontainers is the pattern matured: real Postgres/Kafka/Redis started by the test itself, on demand.

Real-world example

Before: a shared 'test DB' server, permanently half-broken by whoever ran last, plus a wiki page of setup steps for new joiners. After compose + Testcontainers: git clone, one command, identical stack in 90 seconds — and the Slack channel for 'is staging DB down for anyone else?' quietly became unnecessary.

Key points
  • Same image everywhere = no drift
  • Per-run, disposable, parallel-safe
  • Testcontainers: real deps on demand
They'll ask next · tap one for the answer
The trap

'Docker means consistency' hand-waving — name the mechanism: pinned images, per-run stacks, death of the shared mutable environment.

Copy link

Design a CI/CD pipeline for a team shipping daily. What runs where?

CI/CD Pipelinessenior

Staged by feedback speed. On PR (blocking, <10 min): lint, unit, service tests with containerised deps, contract checks, the E2E smoke pack.

Staged by feedback speed. On PR (blocking, <10 min): lint, unit, service tests with containerised deps, contract checks, the E2E smoke pack. On merge → staging deploy: fuller integration + critical journeys, then auto-promote. Production deploy: canary with automated health/SLO checks, auto-rollback. Nightly: full regression, performance baseline, security scans.

Principle: everything blocking must be fast AND trusted — one flake in the gate and developers route around it.

Real-world example

The design decision that made daily shipping real here: the E2E pack on PRs is twelve tests, not two hundred — chosen by 'would we block a deploy if this failed?'. Depth moved nightly. PR gate: 8 minutes, trusted, never bypassed; the previous 40-minute gate had a --no-verify culture within a month.

Key points
  • PR: fast blocking gate <10min
  • Merge: staging + journeys; canary to prod
  • Depth nightly; trust or bypass
They'll ask next · tap one for the answer
The trap

One giant pipeline running everything on every commit — the design that guarantees either slowness or skipping.

Copy link

How do you make a test suite safe to run in parallel?

Parallel Executionmidsenior

Kill every shared mutable thing: unique data per test (UUIDs/run-ids, factories), no shared accounts, no fixed ports/files/globals, no order dependencies, isolated or namespaced external state per…

Kill every shared mutable thing: unique data per test (UUIDs/run-ids, factories), no shared accounts, no fixed ports/files/globals, no order dependencies, isolated or namespaced external state per worker.

Then prove it: run shuffled and parallel in CI as the norm — the failures that appear are your coupling map. Parallel safety is a property you enforce, not an option you flip.

Real-world example

Flipping pytest -n 8 on an 'independent' suite produced 23 failures — the coupling census: a shared admin login (session invalidated across workers), a hardcoded /tmp/report.pdf, tests reading a counter another test incremented. Two weeks of fixes ordered by frequency; parallel has been the default since, and stayed green.

Key points
  • Unique data, no shared accounts
  • No fixed ports/files/order
  • Shuffle+parallel in CI proves it
They'll ask next · tap one for the answer
The trap

'Use pytest-xdist' — the flag is trivial; the engineering is the isolation that makes the flag safe.

Copy link

How would you shard a large test suite across workers efficiently?

Parallel Executionsenior

Balance by recorded duration, not test count: bin-pack tests so every shard finishes together — the suite's wall-clock is its slowest shard.

Balance by recorded duration, not test count: bin-pack tests so every shard finishes together — the suite's wall-clock is its slowest shard. Feed timing data from previous runs, rebalance continuously, and keep shards deterministic enough to debug.

Refinements: quarantine flakes out of the timing signal, split long test FILES if the runner shards by file, and watch shard-finish variance as a health metric.

Real-world example

Count-based split of 2,000 tests across 20 workers: 19 finished in ~6 minutes, one dragged 14 — it had drawn the E2E monsters. Duration-based bin-packing from the last run's timings: all shards within 30 seconds of each other, wall-clock down 40% with zero new hardware.

Key points
  • Bin-pack by duration history
  • Wall-clock = slowest shard
  • Rebalance continuously
They'll ask next · tap one for the answer
The trap

Splitting by count or alphabet — the one slow shard IS the suite's runtime, and it shows in the first question back.

Copy link

Given an array of integers, find if any value appears more than once. What's your approach and complexity?

Coding & DSAjuniormid

Walk the array once, keeping a set of seen values; if the current value is already in the set, there's a duplicate. O(n) time, O(n) space — each element checked once, set operations O(1).

Walk the array once, keeping a set of seen values; if the current value is already in the set, there's a duplicate. O(n) time, O(n) space — each element checked once, set operations O(1).

Say the alternatives to show range: sort first → O(n log n) time but O(1) extra space (if in-place) — the trade-off worth mentioning aloud. Brute-force pairs is O(n²) — name it only to reject it.

Real-world example

def has_duplicate(nums):
    seen = set()
    for n in nums:
        if n in seen:
            return True
        seen.add(n)
    return False

Interview move: state time/space BEFORE being asked, then offer 'if memory is tight, sort-then-scan trades time for space' — that sentence is the difference between solving and engineering.

Key points
  • Set of seen → O(n)/O(n)
  • Sort variant: O(n log n)/O(1)
  • State complexity unprompted
They'll ask next · tap one for the answer
The trap

Jumping to code without stating complexity — in SDET loops the analysis is scored as heavily as the loop.

Copy link

How much data structures and algorithms knowledge does an SDET actually need?

Coding & DSAmidsenior

Solid on the working set: arrays, strings, hash maps/sets, lists, basic trees; two-pointer, sliding window, BFS/DFS at easy-to-medium level; and big-O fluency — because framework code has real…

Solid on the working set: arrays, strings, hash maps/sets, lists, basic trees; two-pointer, sliding window, BFS/DFS at easy-to-medium level; and big-O fluency — because framework code has real performance choices in it.

Not needed: dynamic programming golf, red-black tree internals, competitive tricks. The honest framing: enough DSA to pass a mid developer screen, applied mostly to test-infra problems — log parsing, data generation, result diffing.

Real-world example

Where DSA showed up in my actual test code: deduplicating 40k failure fingerprints (hash map), matching expected-vs-actual order-independent (sets), walking a JSON schema tree for contract diffs (DFS), and a sliding window over response times for a flake-burst detector. Zero LeetCode-hards; hash maps daily.

Key points
  • Maps/sets/strings + easy-medium patterns
  • Big-O for framework choices
  • Applied to infra, not puzzles
They'll ask next · tap one for the answer
The trap

Either extreme — 'none needed' fails the screen; 'grind LeetCode hards' wastes months an SDET should spend on infra skills.

Copy link

Walk me through how you'd approach a coding problem you've never seen in an interview.

Coding & DSAjuniormidsenior

A visible method: restate the problem and confirm; clarify inputs, edges, constraints (sorted? empty? size?); work a small example by hand; state the brute force and its complexity, then improve;…

A visible method: restate the problem and confirm; clarify inputs, edges, constraints (sorted? empty? size?); work a small example by hand; state the brute force and its complexity, then improve; code while narrating; then test it yourself — normal case, edge, empty — before declaring done.

That last step unprompted is the QA signature, and interviewers notice.

Real-world example

The self-test step in action: finished a string problem, then said 'let me try empty string, single char, all-duplicates' — the all-duplicates case exposed an off-by-one I fixed on the spot. Interviewer's feedback later: that unprompted testing moment carried the round more than the solution itself.

Key points
  • Restate → clarify → example
  • Brute force + complexity, then improve
  • Test your own code, unprompted
They'll ask next · tap one for the answer
The trap

Diving into code mid-question-statement — the method IS what's being interviewed; the problem is just the stage.

Copy link

Which design patterns are genuinely useful in test automation?

Design Patternsmidsenior

The working set: Page Object/Component (UI structure), Builder/Factory (test data: aUser().withExpiredCard().build()), Facade (one clean API over messy setup), Strategy (swap browser/env…

The working set: Page Object/Component (UI structure), Builder/Factory (test data: aUser().withExpiredCard().build()), Facade (one clean API over messy setup), Strategy (swap browser/env implementations), Singleton — used sparingly (config; dangerous for drivers in parallel), Observer (listeners for artifacts on failure).

Patterns solve duplication and change-cost; naming which problem each solves in YOUR framework is the answer.

Real-world example

The builder that earned its keep: order tests needed users in a dozen states — anonymous, VIP-with-expired-card, mid-trial. aUser().vip().withExpiredCard().build() made each test's data intent readable in one line, and when the user API changed, one builder changed instead of ninety tests.

Key points
  • POM, Builder, Factory, Facade, Strategy
  • Singleton: config yes, driver caution
  • Pattern = named solution to a cost
They'll ask next · tap one for the answer
The trap

Listing GoF names without a test-code use for each — 'Observer' means nothing; 'screenshot listener on failure' means you've built one.

Copy link

How do the SOLID principles apply to test code?

Design Patternssenior

Directly, with test-shaped meanings. S: a page object does UI structure OR data setup, never both; a test verifies one behaviour.

Directly, with test-shaped meanings. S: a page object does UI structure OR data setup, never both; a test verifies one behaviour. O: add a new browser/env without editing every class — factories and config. L: any implementation of your client interface must be swappable (real vs fake). I: small focused fixtures over god-helpers. D: tests depend on abstractions — an ApiClient interface — not on concrete wiring.

The payoff is the same as in prod code: change costs stay local.

Real-world example

The D in practice: tests spoke to PaymentClient, an interface. Real implementation for integration runs, fake for fast local runs — swapped by fixture, zero test edits. When the provider SDK changed, one adapter class changed. The suite that hardcoded the SDK everywhere spent a sprint on the same migration.

Key points
  • S: one job per class/test
  • O/D: swap via config, not edits
  • Small fixtures over god-helpers
They'll ask next · tap one for the answer
The trap

Reciting SOLID's definitions without a single test-code translation — the question is the translation.

Copy link

What do you look for when reviewing production code as an SDET?

Code Reviewsenior

The testability-and-risk lens developers skim: error paths (what happens when the call fails — is it handled, logged, surfaced?), edge inputs (null/empty/boundary), observability (will we see this…

The testability-and-risk lens developers skim: error paths (what happens when the call fails — is it handled, logged, surfaced?), edge inputs (null/empty/boundary), observability (will we see this fail in prod?), testability (injectable dependencies, or hardwired singletons?), test ids on new UI, and 'which existing tests does this change invalidate?'

SDET review isn't style patrol — it's asking the questions the incident review would ask, earlier.

Real-world example

The review comment that paid for the seat: a new payment retry loop had no cap — on a provider outage it would hammer forever. 'What stops this at attempt 10,000?' became a max-retries + backoff before merge. That's the SDET lens: not 'does it work' but 'how does it fail'.

Key points
  • Error paths and edge inputs
  • Observability + testability
  • Ask how it FAILS
They'll ask next · tap one for the answer
The trap

Reviewing like a linter — naming and formatting — while the uncapped retry loop sails through.

Copy link

Who should write unit tests — developers or QA?

Role & Scopemidsenior

Developers — they know the code's intent, the tests run with their build, and TDD-style feedback only works at the point of writing. Unit tests written by someone else arrive late and test guesses.

Developers — they know the code's intent, the tests run with their build, and TDD-style feedback only works at the point of writing. Unit tests written by someone else arrive late and test guesses.

The SDET's role: make those tests GOOD — review them, push coverage where risk lives, build the harnesses and patterns, and hold the line in the pipeline. Ownership of quality is shared; ownership of unit tests is the author's.

Real-world example

The anti-pattern I was hired into once: a 'QA writes all tests' policy, with unit tests written weeks after the code by people reverse-engineering intent. Coverage was 80%; assertions were guesses. Flipping ownership — devs write, SDET reviews and coaches — halved the count and caught more bugs within a quarter.

Key points
  • Devs write — intent + timing
  • SDET reviews, coaches, gates
  • Late unit tests test guesses
They'll ask next · tap one for the answer
The trap

'QA writes them so devs can focus' — the answer that guarantees late, intent-blind unit tests.

Copy link

What's the difference between line, branch and mutation coverage?

Coverage & Qualitysenior

Line: did this line execute? Branch: did BOTH sides of each if run? — stricter, catches the untested else.

Line: did this line execute? Branch: did BOTH sides of each if run? — stricter, catches the untested else. Mutation: change the code (flip a comparison, delete a call) and see if any test fails — measuring whether tests would actually CATCH bugs, not whether code ran.

The ladder of honesty: line says code executed, branch says paths executed, mutation says the tests can detect change. Only the last one measures test QUALITY.

Real-world example

A payments module: 95% line coverage, applause. Mutation run: 40% of mutants survived — including flipping >= to > in the discount threshold with every test still green. The tests executed the code and asserted almost nothing about it. That gap between 95 and 40 is the whole story of coverage theatre.

Key points
  • Line: executed; branch: both paths
  • Mutation: would tests CATCH a bug?
  • High line + surviving mutants = theatre
They'll ask next · tap one for the answer
The trap

Explaining line vs branch and hand-waving mutation — mutation is the one that measures the thing everyone assumes coverage measures.

Copy link

Your manager wants 100% code coverage as a KPI. How do you respond?

Coverage & Qualitysenior

Redirect, don't refuse: coverage as a KPI invites gaming — tests with no assertions hit any number — and the last 15% (getters, glue, config) costs the most while catching the least.

Redirect, don't refuse: coverage as a KPI invites gaming — tests with no assertions hit any number — and the last 15% (getters, glue, config) costs the most while catching the least.

Counter-offer something measurable and honest: high coverage on changed lines per PR, mutation spot-checks on critical modules, escaped-defect trend, flake rate. Say yes to the goal (confidence), no to the proxy (a single percentage).

Real-world example

Seen the KPI version play out: team hit 100% in a quarter — by generating tests that called everything and asserted nothing. Coverage 100%, escaped defects unchanged, and now a thousand meaningless tests to maintain. The number arrived; the confidence it was supposed to represent never did.

Key points
  • Targets get gamed — Goodhart
  • Changed-lines + mutation instead
  • Yes to confidence, no to the proxy
They'll ask next · tap one for the answer
The trap

Either saluting the KPI or lecturing about Goodhart's law with no alternative — the job is the counter-proposal.

Copy link

What is mutation testing, and would you actually use it?

Coverage & Qualitysenior

Tooling (PIT, Stryker, mutmut) seeds small code changes — flipped comparisons, deleted calls, changed constants — and runs your tests: a mutant your suite kills is fine; a surviving mutant is a bug…

Tooling (PIT, Stryker, mutmut) seeds small code changes — flipped comparisons, deleted calls, changed constants — and runs your tests: a mutant your suite kills is fine; a surviving mutant is a bug shape your tests would miss.

Would I use it? Yes, surgically: critical modules (money, auth, pricing) on a schedule or on-change — not suite-wide in CI, because it's compute-heavy. It's an audit tool, not a gate.

Real-world example

First mutmut run on our pricing module: 61 mutants, 19 survived — one was 'delete the rounding call' with all tests green, which explained a real penny-drift bug from the previous quarter. Four hours of strengthening assertions killed 17 of the 19. That module's tests have caught two regressions since.

Key points
  • Seed bugs, see if tests notice
  • Survivors = blind spots, listed
  • Surgical use on critical modules
They'll ask next · tap one for the answer
The trap

'Sounds academic' — it's the only common tool that measures whether your tests test; dismissing it reads as never having run it.

Copy link

What quality gates would you put in a pipeline, and what should actually block a merge?

CI/CD Pipelinessenior

Blocking on PR: build, lint/type checks, unit + service tests, contract verification, security scan on dependencies (fail on known-critical CVEs), the E2E smoke pack, coverage-on-changed-lines…

Blocking on PR: build, lint/type checks, unit + service tests, contract verification, security scan on dependencies (fail on known-critical CVEs), the E2E smoke pack, coverage-on-changed-lines tripwire. Observing, not blocking: full regression, performance baselines, mutation scores — reported, trended, acted on, but not standing between a dev and a merge.

The discipline: a blocking gate must be fast and trusted; every flake in it debases the whole pipeline's currency.

Real-world example

We moved performance checks from blocking to observed after two false-alarm weeks — CI runner noise made latency gates cry wolf, and people started rubber-stamping overrides. As a nightly trend with alerting, the same checks caught a real 30% regression a month later — and were believed, because they'd stopped lying.

Key points
  • Block: fast, deterministic, trusted
  • Observe: slow/noisy but valuable
  • Flaky gate = debased currency
They'll ask next · tap one for the answer
The trap

Blocking on everything 'for safety' — the pipeline that takes 90 minutes and gets bypassed is less safe than the 10-minute one people obey.

Copy link

How would you test a database migration?

Data & Messagingsenior

Beyond 'it ran': correctness — row counts, checksums/aggregates and spot-diffs between old and new shapes; integrity — constraints, foreign keys, nothing orphaned; the rollback — actually execute it,…

Beyond 'it ran': correctness — row counts, checksums/aggregates and spot-diffs between old and new shapes; integrity — constraints, foreign keys, nothing orphaned; the rollback — actually execute it, don't just trust the script's existence; performance at production scale — a migration instant on 10k staging rows can lock a 50M-row table for an hour; and the app during migration — old code against new schema (or the expand/contract pattern) for zero-downtime deploys.

Real-world example

The near-miss that wrote this checklist: a column-type migration tested fine on staging's 8k rows. Against a production-sized copy it took 47 minutes holding a table lock — checkout would have been down the whole time. Re-written as an online, batched backfill; the scale rehearsal is now non-negotiable for any migration touching hot tables.

Key points
  • Counts + checksums + integrity
  • Execute the rollback, at scale
  • Old app vs new schema (expand/contract)
They'll ask next · tap one for the answer
The trap

'Run it on staging and check it worked' — staging's data size makes that a rehearsal of nothing.

Copy link

How do you test an event-driven system using a message queue like Kafka?

Data & Messagingsenior

Test the guarantees, not just the plumbing: producers emit the right events (schema + content — consume and assert); consumers are idempotent (redeliver the same event — exactly one effect); ordering…

Test the guarantees, not just the plumbing: producers emit the right events (schema + content — consume and assert); consumers are idempotent (redeliver the same event — exactly one effect); ordering assumptions hold within partitions; failures route to retries/DLQ rather than vanishing; and lag under load stays sane.

Async needs async assertions: poll-until-consistent with timeouts, never sleep-and-hope. Testcontainers Kafka makes all this runnable per-build.

Real-world example

The bug this approach catches every time: order-service redelivered a payment-completed event after a consumer restart, and the loyalty service granted points twice. The test that now guards it is three lines of intent: publish event, publish it again, assert points == once. Every consumer gets that test as a template.

Key points
  • Consumer idempotency: redeliver test
  • Schema/contract on events
  • DLQ paths + poll-based assertions
They'll ask next · tap one for the answer
The trap

Testing only the happy publish-consume path — event systems earn their complexity in redelivery, ordering and failure, which is where the tests belong.

Copy link

What security testing should be part of a normal QA process?

Security Testingmidsenior

The layer below pentesting is QA's job: authz on every endpoint (other user's ID → 403 — IDOR hunting), input handling (injection payloads in the standard test set), authentication seams (expiry,…

The layer below pentesting is QA's job: authz on every endpoint (other user's ID → 403 — IDOR hunting), input handling (injection payloads in the standard test set), authentication seams (expiry, revocation, rate limits), secrets hygiene (nothing in logs, URLs, or client storage), dependency scanning in CI, and security headers/cookie flags as automated checks.

Framed as test design: abuse cases alongside use cases, every feature.

Real-world example

Routine authz sweep on a new export endpoint: change the account ID in the request — full CSV of another company's customers. No pentest scheduled for months; the check that caught it was a standing two-line test pattern applied to every new endpoint. That's QA-layer security: unglamorous, constantly catching real ones.

Key points
  • IDOR sweep on every endpoint
  • Injection set + auth seams
  • Secrets/logs + dependency CVEs in CI
They'll ask next · tap one for the answer
The trap

'Security is the security team's job' — the answer that ships the IDOR your two-line test would have caught.

Copy link

What is observability, and how does it change how you test?

Observabilitysenior

The system's ability to explain itself from outputs — logs, metrics, traces — so you can ask new questions of production without redeploying.

The system's ability to explain itself from outputs — logs, metrics, traces — so you can ask new questions of production without redeploying. Monitoring watches known failure modes; observability lets you debug unknown ones.

It changes testing three ways: it's a testable requirement (does this feature emit the events/metrics we'd need in an incident?), it extends testing into production (canaries, SLO-based release gates), and it's a debugging tool for the test system itself.

Real-world example

Incident review question that changed our checklist: 'could we have SEEN this before users reported it?' The answer was no — the failing flow logged nothing distinct. Now stories carry an observability acceptance criterion, and QA verifies the emit: break the flow in staging, confirm the alert fires. We test the smoke detector, not just the stove.

Key points
  • Logs + metrics + traces = ask anything
  • Observability is a requirement to TEST
  • Break it in staging; expect the alert
They'll ask next · tap one for the answer
The trap

Treating it as ops vocabulary — the SDET version is 'observability is a feature I test and a tool I use', with one example of each.

Copy link

How do feature flags change your testing strategy?

CI/CD Pipelinessenior

They split deploy from release — which moves some testing AFTER deploy, behind the flag: test on in production safely (flag on for test accounts), roll out gradually watching metrics.

They split deploy from release — which moves some testing AFTER deploy, behind the flag: test on in production safely (flag on for test accounts), roll out gradually watching metrics.

New obligations: test both states of consequential flags (off must stay safe — it's the rollback), watch for interactions between flags, keep a flag-hygiene process (expired flags are latent bugs), and know the kill-switch works — actually flip it.

Real-world example

The flag bug that teaches the 'both states' rule: new checkout behind a flag, thoroughly tested ON. Rollback day came, flag OFF — and the old path broke, because a shared component had drifted assuming the new flow. The rollback WAS the incident. Off-state tests on money flags are non-negotiable since.

Key points
  • Deploy ≠ release; test-on-prod safely
  • Both states — off is the rollback
  • Flag hygiene + kill-switch drills
They'll ask next · tap one for the answer
The trap

Only the happy story — flags as pure enablement. The off-state rollback bug is the half interviewers are checking you've met.

Copy link

What is canary or blue-green deployment, and how do you test with it?

CI/CD Pipelinessenior

Blue-green: two identical environments; deploy to the idle one, verify, switch traffic — rollback is switching back.

Blue-green: two identical environments; deploy to the idle one, verify, switch traffic — rollback is switching back. Canary: new version to a small slice (1–5%), watch error rate/latency/business metrics against baseline, widen or roll back.

Testing's role: define the health checks that gate promotion (automated, not vibes), smoke the idle/canary before traffic, and verify the rollback path itself — unrehearsed rollbacks fail when needed most.

Real-world example

Canary catch from the metric set: 2% rollout, technical metrics clean — but orders/min on the canary slice ran 8% under baseline. A UI regression had made the coupon field invisible on one browser; no test had it, the business metric did. Auto-rollback fired before the third coffee. That's testing extended into production.

Key points
  • Blue-green: switch; canary: slice + widen
  • Automated promotion gates, incl. business metrics
  • Rehearse the rollback
They'll ask next · tap one for the answer
The trap

Describing the traffic mechanics without testing's role — the gates, the pre-traffic smoke, and the rollback drill are the SDET content.

Copy link

How is testing a GraphQL API different from testing REST?

API & Contract Testingsenior

One endpoint, infinite queries — so testing shifts from 'per endpoint' to per operation and per resolver: field-level authz (can this role see THIS field — the classic leak), query depth/complexity…

One endpoint, infinite queries — so testing shifts from 'per endpoint' to per operation and per resolver: field-level authz (can this role see THIS field — the classic leak), query depth/complexity limits (nested-query DoS), N+1 resolver performance, error shape (200 OK with an errors array — your assertions must read the body), and schema evolution (deprecations instead of versioning).

The mental shift: the schema is enormous surface area; clients choose their own slice of it.

Real-world example

The GraphQL-specific find: user query allowed selecting internalNotes — a field the REST API never exposed. Authz was checked per-query, not per-field, so any authenticated user could request it by name. Field-level authorization tests on sensitive types became a standing pattern that day.

Key points
  • Field-level authz, not just endpoint
  • Depth/complexity limits vs DoS
  • Errors arrive as 200 + errors[]
They'll ask next · tap one for the answer
The trap

'Same as REST, one endpoint' — field authz, complexity attacks and the 200-with-errors shape are exactly where GraphQL bites the REST playbook.

Copy link

What is chaos engineering, and would you use it?

System Design for Testsenior

Deliberately injecting failure — killed instances, latency, dropped dependencies — to verify the system's resilience claims hold: retries retry, failovers fail over, alerts alert.

Deliberately injecting failure — killed instances, latency, dropped dependencies — to verify the system's resilience claims hold: retries retry, failovers fail over, alerts alert. Hypothesis-driven and blast-radius-limited, not vandalism.

Would I use it? Yes, scaled to context: staging fault injection for every resilience feature (that's just testing), and controlled production experiments only once observability and rollback are mature. It's the test suite for the '-ilities' everyone claims and nobody verifies.

Real-world example

Entry-level chaos that found gold: kill the recommendations service in staging — the product page was supposed to degrade gracefully. It hung for 30s instead: the timeout was configured but a retry loop sat in front of it. Every 'we handle that failure' claim now gets the same treatment: prove it by causing it.

Key points
  • Inject failure, verify the claim
  • Hypothesis + limited blast radius
  • Staging first; prod needs maturity
They'll ask next · tap one for the answer
The trap

'Netflix randomly breaks prod' folklore — the discipline is hypothesis, blast radius and measurement, and it starts in staging.

Copy link

How do you decide whether a bug is worth fixing before release?

Role & Scopesenior

Frame it as risk vs risk — the bug's cost (impact × reach × workaround) against the fix's cost THIS close to release (change risk, retest scope, delay).

Frame it as risk vs risk — the bug's cost (impact × reach × workaround) against the fix's cost THIS close to release (change risk, retest scope, delay). Add reversibility: can we flag it off, hotfix tomorrow, or is it burned into a mobile release for weeks?

Then my actual job: make that trade visible to the owner in plain numbers, recommend, and record the decision. QA rarely owns the call; QA always owns its honesty.

Real-world example

Two bugs, same release-eve: a rare crash in a legacy report (workaround exists, fix touches shared code — deferred, flagged, ticketed) and a rounding error of one cent per order (invisible to users, but money and irreversible at volume — release slipped a day). Same severity label on paper; opposite calls, both defensible aloud.

Key points
  • Bug risk vs fix-now risk
  • Reversibility changes everything
  • Make it visible; record the call
They'll ask next · tap one for the answer
The trap

A severity-table answer — the question is about judgment under release pressure, and 'it depends' with named factors IS the strong answer.

Copy link

A test fails intermittently in CI. Walk me through your debugging process.

Debuggingmidsenior

Evidence before theories: pull the CI artifacts (trace, screenshot, video, logs) from several failures and diff them — same step every time, or scattered?

Evidence before theories: pull the CI artifacts (trace, screenshot, video, logs) from several failures and diff them — same step every time, or scattered? Then reproduce deliberately: run it in a loop under CI-like conditions (headless, parallel, same resources).

Pattern → hypothesis → targeted fix: same step = timing race there; only-in-parallel = shared state; random steps = environment/resources. Quarantine meanwhile so the team keeps trusting red — and check whether it's the PRODUCT racing, not the test.

Real-world example

Five failure traces, one pattern: always the assertion after 'save', and always at high parallelism. The save API was returning before the read-replica caught up — a real product race, not a test bug. The 'flaky test' became a consistency bug ticket with five traces attached. Diagnosis order matters precisely because this outcome is common.

Key points
  • Artifacts from multiple failures first
  • Loop-reproduce under CI conditions
  • Pattern names the cause class
They'll ask next · tap one for the answer
The trap

'Add a retry / increase the timeout' as step one — that's suppression; the question is a diagnosis question.

Copy link

How would you reduce a 3-hour test suite to under 30 minutes?

Test Architecturesenior

Measure first — timing report, find where the hours live. Then in payoff order: parallelise (usually the single biggest step — needs isolation work); push tests down a layer (UI checks that are…

Measure first — timing report, find where the hours live. Then in payoff order: parallelise (usually the single biggest step — needs isolation work); push tests down a layer (UI checks that are really API/unit checks — often a third of the runtime); kill duplicated setup (API login vs 200 UI logins, shared fixtures per worker); delete/merge redundant tests after a coverage audit; split by purpose (blocking smoke vs nightly depth) so the 30-minute target applies to what gates merges.

Real-world example

Real numbers from doing exactly this: 3h04 → measured: 40% was UI tests re-verifying business rules (moved to API layer: −70 min), UI login per test (storageState: −25 min), then 8-way parallel on the remainder (−60 min). Final: 27 minutes blocking, with the long tail split into a nightly. No test of value was lost — that's the constraint that makes it engineering.

Key points
  • Profile before touching anything
  • Parallel + layer-push = the big wins
  • Split blocking vs nightly
They'll ask next · tap one for the answer
The trap

'Parallelise it' as the whole answer — parallelism is one lever, and useless on a suite whose tests can't run independently.

Copy link

How would you introduce automation to a team that has none?

Role & Scopesenior

Start where the pain is loudest and the win is fastest: a smoke pack on the critical path, in CI, week one — ten tests that run on every build and visibly catch things. Not a framework odyssey.

Start where the pain is loudest and the win is fastest: a smoke pack on the critical path, in CI, week one — ten tests that run on every build and visibly catch things. Not a framework odyssey.

Then grow by demonstrated value: regression on the areas that bite, API layer as it stabilises, teach as you build (pairing, templates) so it's the team's capability, not your fiefdom — and report wins in team language: 'caught before merge', 'release testing dropped from 3 days to 1'.

Real-world example

Team of manual testers, zero automation, skeptical: week one was ten Playwright smoke tests wired to CI — no page objects yet, deliberately. Week three, the smoke caught a broken login before a demo, and the skeptics asked how to add tests. THEN came the framework structure, built with them. Sequence sold it; a framework-first month would have produced architecture and zero believers.

Key points
  • Smoke in CI, week one
  • Value before architecture
  • Teach as you build — no fiefdoms
They'll ask next · tap one for the answer
The trap

Starting with a framework-selection matrix — the team needs a caught bug, not a comparison spreadsheet.

Copy link

How do you test a machine learning or AI-powered feature?

System Design for Testsenior

Split deterministic from probabilistic. Deterministic (normal testing): the pipeline, feature extraction, API contracts, fallbacks when the model fails or times out.

Split deterministic from probabilistic. Deterministic (normal testing): the pipeline, feature extraction, API contracts, fallbacks when the model fails or times out. Probabilistic (new discipline): golden datasets with expected outputs, quality metrics with thresholds instead of exact asserts (accuracy ≥ X on the eval set), regression checks between model versions, bias/edge-slice evaluation, and production monitoring for drift.

The mindset shift: from 'is the answer correct' to 'is the quality distribution acceptable — and stable'.

Real-world example

A support-ticket classifier: instead of asserting ticket #123 → 'billing', the eval job scores each model version on a 2,000-ticket golden set — overall accuracy plus per-category, with a hard gate on 'refund' recall (the expensive miss). Version 12 raised overall accuracy but dropped refund recall 9% — exactly the trade the gate existed to catch. Shipped rolled back; that's ML testing doing its job.

Key points
  • Deterministic parts: normal tests
  • Golden sets + threshold metrics
  • Per-slice gates; monitor drift
They'll ask next · tap one for the answer
The trap

Asserting exact outputs — the first flake teaches you why; the discipline is thresholds on distributions, not equality on answers.

Copy link

What would you do in your first 90 days as an SDET on a new team?

Role & Scopesenior

Days 1–30, learn before touching: ship something small but real (a fixed flake, a missing smoke test) while mapping the product's money paths, the team's actual pain (ask everyone 'what breaks…

Days 1–30, learn before touching: ship something small but real (a fixed flake, a missing smoke test) while mapping the product's money paths, the team's actual pain (ask everyone 'what breaks most?'), and the existing test estate honestly.

31–60, targeted wins: attack the top pain — usually flake, runtime, or a coverage hole — with measurable before/after. 61–90, structure: the improvement plan with the team's fingerprints on it, standards agreed in review, and one metric trending publicly (flake rate, PR-gate time).

Real-world example

The day-one-month question that shaped everything: 'what breaks most?' — every answer said the nightly suite, red 4 mornings of 5, ignored by all. Fixing THAT first (quarantine + top-ten flakes) bought more credibility than any framework could; by day 90 the suite gated releases again and the team asked for the standards, rather than receiving them.

Key points
  • Learn + small real win first
  • Attack the loudest pain, measure it
  • Structure with the team, not at it
They'll ask next · tap one for the answer
The trap

Arriving with a 90-day framework-rebuild plan — the question screens for humility-before-change, not for ambition.

Copy link

How do you know your test suite is actually good?

Coverage & Qualitysenior

By outcomes, not size: escaped defects trending down (the north star — bugs production finds that the suite should have), defect detection ratio (what share of real bugs the suite catches first),…

By outcomes, not size: escaped defects trending down (the north star — bugs production finds that the suite should have), defect detection ratio (what share of real bugs the suite catches first), flake rate near zero (red is believed), speed that gates without being bypassed, and mutation spot-checks proving tests can actually fail.

The uncomfortable summary: a suite's quality is measured by what gets past it, and most teams never look.

Real-world example

The audit that reframed ours: six months of production bugs, each tagged 'should the suite have caught this?' — 60% yes, and 80% of THOSE clustered in two modules with high coverage and weak assertions. Test count said healthy; the escaped-defect review said exactly where it lied. That review is now quarterly.

Key points
  • Escaped defects = the north star
  • Believed red + un-bypassed speed
  • Audit what got past it
They'll ask next · tap one for the answer
The trap

Answering with counts and coverage — the question is 'how do you KNOW', and only outcome metrics know.

Copy link

Tell me about a time your testing missed something important. What happened?

Role & Scopemidsenior

Bring a real one, structured: what escaped, the specific gap that let it (not 'time pressure' — the actual hole in test design), the blast radius and cleanup, and the systemic fix — what changed so…

Bring a real one, structured: what escaped, the specific gap that let it (not 'time pressure' — the actual hole in test design), the blast radius and cleanup, and the systemic fix — what changed so the CLASS of bug is covered, not just the instance.

Scored almost entirely on ownership: one sentence of blame-free honesty about the miss, three about the judgment that followed.

Real-world example

Mine: a currency-rounding bug — orders in JPY (no decimal places) charged 100× intended for a day. My gap: every payment test used USD; currency was a fixture constant nobody varied. Fix beyond the bug: currency became a first-class test dimension (JPY, KWD's three decimals, EUR), plus a production reconciliation alert on charge-vs-cart mismatch. The alert has since caught an unrelated bug — the systemic fix outlived the incident.

Key points
  • Name the real design gap
  • Fix the class, not the instance
  • Ownership tone carries the answer
They'll ask next · tap one for the answer
The trap

Choosing a story where you weren't really at fault — the question exists to watch you own something, and dodges are transparent.

Copy link

Where do you see the QA role going, and how are you preparing?

Role & Scopemidsenior

Consolidating upward: routine execution and artefact-writing are being automated (lately accelerated by AI), while the durable core grows — test strategy and risk judgment, quality engineering across…

Consolidating upward: routine execution and artefact-writing are being automated (lately accelerated by AI), while the durable core grows — test strategy and risk judgment, quality engineering across the pipeline, testing the new hard things (ML features, event-driven systems), and being the person who can REVIEW machine-generated tests rather than hand-write everything.

Preparation, concretely: engineering depth (the SDET path itself), production/observability fluency, and using AI as a drafting tool while owning the judgment layer it can't do.

Real-world example

How the AI shift lands in practice: I use it to draft test cases and boilerplate — first-draft speed roughly doubled — but the value moved to the review: knowing which generated cases are redundant, which edge case it missed (it never varies currency…), and what NOT to automate. The tool made the judgment more valuable, not less. That's the bet I'm making with my own learning time.

Key points
  • Execution automates; judgment appreciates
  • Quality engineering across the pipeline
  • AI as drafter, human as reviewer
They'll ask next · tap one for the answer
The trap

Either doom ('QA is dying') or denial ('nothing changes') — the hireable answer is the shift you're skating toward, with evidence you've started.

Copy link

Why do test teams use Docker at all?

Containers & Infrastructuremidsenior

It kills "works on my machine". Docker packages the test environment — browser version, drivers, dependencies, config — into an image that runs identically on your laptop, a colleague's, and CI.

It kills "works on my machine". Docker packages the test environment — browser version, drivers, dependencies, config — into an image that runs identically on your laptop, a colleague's, and CI. Same image, same result.

Before it, a suite passed locally and failed in CI over a Chrome version or a missing library, and you'd lose a day to it. With Docker the runner and your machine execute the byte-identical environment, so an environment difference stops being a suspect.

Real-world example

A suite failed only in CI because the runner had Chrome 120 and the dev had 124. Pinning a Selenium Docker image with a fixed browser version made the two environments identical and the failure vanished.

Key points
  • Packages the whole test environment into a reproducible image
  • Same image runs identically locally and in CI
  • Removes 'works on my machine' environment drift
They'll ask next · tap one for the answer
Copy link

How do you run browser tests inside Docker?

Containers & Infrastructuremidsenior

Use a prebuilt image that already has the browser and driver — the official Selenium (selenium/standalone-chrome) or Playwright images — so you're not installing a browser by hand.

Use a prebuilt image that already has the browser and driver — the official Selenium (selenium/standalone-chrome) or Playwright images — so you're not installing a browser by hand. Run headless, and mount a volume to pull out screenshots, videos and traces after the run.

The gotcha everyone hits: Chrome crashes in a container because the default /dev/shm is too small. Either raise it (--shm-size=2g) or run with --disable-dev-shm-usage. Not knowing that one is the tell of someone who's never actually containerised a browser suite.

Key points
  • Prebuilt Selenium/Playwright images ship the browser + driver
  • Headless, with a volume for screenshots/videos/traces
  • Raise --shm-size or --disable-dev-shm-usage — the classic Chrome crash
They'll ask next · tap one for the answer
The trap

Not knowing the /dev/shm crash gives you away — it's the first wall anyone running Chrome in Docker hits, so interviewers use it to check real experience.

Copy link

What does Docker Compose give you for test environments?

Containers & Infrastructuresenior

Compose spins up a whole multi-service environment from one file — the app under test, its database, a message queue, a Selenium node — all networked together, with one command.

Compose spins up a whole multi-service environment from one file — the app under test, its database, a message queue, a Selenium node — all networked together, with one command. Your tests get a real, isolated stack instead of mocks or a shared staging everyone fights over.

The payoff is a clean slate every run: bring it up, seed data, test, tear it down. No leftover state, no "someone changed staging", and the same stack in CI as locally. It's how you make integration tests reproducible.

Key points
  • One file brings up app + db + deps, networked
  • A real isolated stack per run, not shared staging
  • Up → seed → test → tear down; clean slate every time
They'll ask next · tap one for the answer
Copy link

Selenium Grid or a cloud grid — when would you use each?

Containers & Infrastructuresenior

Selenium Grid (often run as Docker containers) is your own hub with browser nodes — you control it, it's cheap at scale, and it's private.

Selenium Grid (often run as Docker containers) is your own hub with browser nodes — you control it, it's cheap at scale, and it's private. A cloud grid (BrowserStack, Sauce Labs) rents browsers and real devices on demand — no infrastructure to maintain, huge browser/OS matrix, but per-minute cost.

Rule of thumb: self-hosted Grid for heavy, steady parallel runs where you want control and low cost; cloud grid when you need real devices, obscure browser/OS combos, or don't want to run infrastructure. Many teams use both — Grid for the bulk, cloud for the long tail of compatibility.

Key points
  • Grid: self-hosted, controlled, cheap at scale, private
  • Cloud grid: on-demand real devices + wide matrix, per-minute cost
  • Grid for steady bulk runs; cloud for real devices / rare combos
They'll ask next · tap one for the answer
Copy link

How does Docker make CI test runs reproducible?

Containers & Infrastructuremidsenior

The CI job runs your tests inside the same pinned image you use locally, so the browser, drivers, language runtime and libraries are byte-identical everywhere.

The CI job runs your tests inside the same pinned image you use locally, so the browser, drivers, language runtime and libraries are byte-identical everywhere. A green run today reproduces next month because the environment is frozen in the image, not assembled fresh each time.

That's the difference between a flaky pipeline and a trustworthy one: without it, CI installs 'latest' of everything and a silent upstream bump breaks you overnight. Pin the image tag (not :latest) and the environment stops being a variable.

Key points
  • CI runs tests in the same pinned image as local
  • Environment frozen in the image — reproducible over time
  • Pin the tag, never :latest, or an upstream bump breaks you
They'll ask next · tap one for the answer
Copy link

A container passes tests but the same code fails on a VM — where do you look?

Containers & Infrastructuresenior

The environments differ somewhere the container hides. Check the obvious deltas: browser/driver versions baked into the image vs installed on the VM, headless vs headed, available memory and…

The environments differ somewhere the container hides. Check the obvious deltas: browser/driver versions baked into the image vs installed on the VM, headless vs headed, available memory and /dev/shm, timezone and locale, and filesystem/permission differences.

The method is to shrink the gap: run the VM's exact browser version headless locally, or better, run the tests in the same container on the VM. Reproducing the delta beats theorising — most 'only on the VM' bugs are a version or a resource limit the container quietly standardised away.

Key points
  • Diff the environments: versions, headless, memory/shm, locale
  • Reproduce by running the container ON the VM
  • Most 'only here' bugs are a version or resource the image standardised
They'll ask next · tap one for the answer
Copy link

In a CI pipeline, what runs at which stage — per-PR, nightly, at release?

CI/CD Pipelinessenior

Fast and focused on every PR: unit tests, a smoke suite, linting — minutes, because it gates the merge and people wait on it.

Fast and focused on every PR: unit tests, a smoke suite, linting — minutes, because it gates the merge and people wait on it. The full regression and cross-browser matrix run nightly or on merge to main, where a longer runtime is fine. Heavier, slower checks — full E2E, performance, security scans — go on a schedule or pre-release.

The principle is feedback speed matched to blast radius: what blocks a developer must be fast; what can take an hour runs where nobody's waiting. Putting the two-hour suite on every push is how teams learn to ignore CI.

Key points
  • Per-PR: unit + smoke + lint, minutes, gates the merge
  • Nightly / on-merge: full regression + cross-browser
  • Scheduled / pre-release: E2E, performance, security
They'll ask next · tap one for the answer
Copy link

The suite is getting slow in CI. How do you keep it fast?

CI/CD Pipelinessenior

Parallelise first — split tests across runners or threads; a suite that runs serially in 40 minutes can finish in 5 across 8 workers.

Parallelise first — split tests across runners or threads; a suite that runs serially in 40 minutes can finish in 5 across 8 workers. Then push work down the pyramid: if an API or unit test can cover it, don't spend a UI test on it. Split fast checks (per-PR) from slow ones (nightly). Cache dependencies and Docker layers so setup isn't rebuilt every run.

And fix the flaky tests rather than retrying them — reruns hide slowness and double the cost. The goal is that the gate a developer waits on stays under a few minutes as the suite grows.

Key points
  • Parallelise across runners/threads — the biggest lever
  • Push coverage down the pyramid; cache deps and image layers
  • Split fast per-PR checks from slow nightly ones; fix flakes, don't retry
They'll ask next · tap one for the answer
Copy link

A test is flaky in CI. What do you actually do about it?

CI/CD Pipelinesmidsenior

Measure it, then quarantine it with a paper trail — don't blanket-retry. First run it enough to get a real failure rate, so 'flaky' is a number not a feeling.

Measure it, then quarantine it with a paper trail — don't blanket-retry. First run it enough to get a real failure rate, so 'flaky' is a number not a feeling. Then mark it (a quarantine tag that keeps it out of the merge gate), ticket it, and give it an owner, the same day.

The anti-pattern is auto-retrying every failure. Retries hide the flake, cost runtime, and teach the team that red means 'run it again' — so a real regression gets ignored with the rest. Quarantine keeps the gate honest while the fix is queued; it doesn't delete the coverage silently.

Key points
  • Measure the real failure rate before calling it flaky
  • Quarantine (tag out of the gate) + ticket + owner, same day
  • Don't blanket-retry — it hides flakes and erodes trust in red
They'll ask next · tap one for the answer
The trap

"Add a retry" as the whole answer. Retrying is triage at best and a coverage-blinding habit at worst — the senior answer measures and quarantines with a ticket.

Copy link

How do you handle test data and environments in CI?

CI/CD Pipelinessenior

Each run gets clean, isolated data it owns — seeded via the API or a fixture at the start, torn down after — never a dependency on a shared, hand-maintained record.

Each run gets clean, isolated data it owns — seeded via the API or a fixture at the start, torn down after — never a dependency on a shared, hand-maintained record. Environments are provisioned reproducibly (a Compose stack or an ephemeral namespace), not a single staging every pipeline fights over.

Secrets — API keys, DB credentials — come from the CI secret store injected at run time, never committed. The whole point is that two runs, or two parallel jobs, can't corrupt each other's state or leak credentials.

Key points
  • Per-run isolated data: seed in setup, tear down after
  • Reproducible environments, not one shared staging
  • Secrets from the CI store at run time, never committed
They'll ask next · tap one for the answer
Copy link

What makes a good CI test report?

CI/CD Pipelinesmidsenior

It answers 'what broke and why' without opening a terminal. Pass/fail counts and duration up top, then each failure with its assertion, and the artifacts that let you debug it — screenshot, video or…

It answers 'what broke and why' without opening a terminal. Pass/fail counts and duration up top, then each failure with its assertion, and the artifacts that let you debug it — screenshot, video or trace, and logs — attached, not described. Trends over time flag a test that's slowly getting flakier.

The test is whether a teammate can triage a red build from the report alone. If they have to re-run locally to understand a failure, the report failed. Publish it where the team already looks — the PR, the CI dashboard — not a file nobody opens.

Key points
  • Counts + duration + each failure's assertion, at a glance
  • Debug artifacts attached: screenshot, video/trace, logs
  • Triage from the report alone; publish where the team looks
They'll ask next · tap one for the answer
Copy link

How would you design a test automation framework from scratch?

Test Architecturesenior

In layers, each with one job. A core/util layer (driver setup, waits, config). A page/service layer that wraps the app (Page Objects for UI, a client layer for API) so locators and endpoints live in…

In layers, each with one job. A core/util layer (driver setup, waits, config). A page/service layer that wraps the app (Page Objects for UI, a client layer for API) so locators and endpoints live in one place. A test layer that reads as intent and asserts. Data handled by fixtures/factories, config from the environment, results in a report, all run in CI.

The test I'd apply: a UI change touches one page class, a new endpoint is one client method, and a test states what it checks, not how. If a locator change ripples into fifty tests, the layering's wrong.

Key points
  • Layers: core/util · page-or-service · tests · data · config · reporting
  • Locators/endpoints defined once, behind an intent-level API
  • A change touches one layer; tests express what, not how
They'll ask next · tap one for the answer
Copy link

How do you structure test data — fixtures, factories, or seeding?

Test Architecturesenior

Use all three for what each is good at. Fixtures give a test its setup/teardown lifecycle (a logged-in session, a temp file).

Use all three for what each is good at. Fixtures give a test its setup/teardown lifecycle (a logged-in session, a temp file). Factories build objects with sensible defaults and only the fields a test cares about overridden — makeUser(role="admin") — so tests aren't buried in boilerplate. Seeding puts data into the system up front, via the API or DB, so a test has something to act on.

The rule across all three is isolation: a test creates what it needs and cleans up, so nothing depends on a shared record. That's what keeps the suite parallel-safe and repeatable.

Key points
  • Fixtures for lifecycle, factories for objects-with-defaults, seeding for starting data
  • Override only the fields a test cares about
  • Every test owns and cleans its data — the isolation rule
They'll ask next · tap one for the answer
Copy link

How do you handle configuration and secrets across environments?

Test Architecturemidsenior

Config (base URLs, timeouts, which environment) comes from outside the code — environment variables or per-environment config files the run selects — never hardcoded, so the same suite runs against…

Config (base URLs, timeouts, which environment) comes from outside the code — environment variables or per-environment config files the run selects — never hardcoded, so the same suite runs against dev, staging or a container by changing one input. Secrets (API keys, credentials) come from a secret store or CI-injected env vars at run time, and never touch the repo.

The test of it: switching from local to CI to a new environment is a config change, not a code change. And a grep of the repo for a real credential returns nothing.

Key points
  • Config from env vars / per-env files, selected at run time
  • Secrets from a store or CI, injected at run time — never committed
  • New environment = config change, not code change
They'll ask next · tap one for the answer
The trap

A committed credential — even in 'just test config' — is an instant red flag. Secrets belong in the CI store, injected at run time, never in the repo.

Copy link

What are the trade-offs of Page Object Model versus a screenplay/component approach?

Test Architecturesenior

Page Object Model maps a class to each page/component, holding its locators and actions — simple, universally understood, and the right default.

Page Object Model maps a class to each page/component, holding its locators and actions — simple, universally understood, and the right default. Its weakness shows at scale: page classes bloat, and reusable interactions get duplicated across pages.

Screenplay (actors performing tasks) and component-based models compose small, reusable interactions instead of page-sized classes — more flexible for large suites, but more concepts to learn and easier to over-engineer. Honest answer: POM for most teams; reach for the alternatives only when POM is visibly straining under duplication and giant page classes.

Key points
  • POM: class per page, simple, universal — the right default
  • Screenplay/component: composable tasks, better at scale, more complexity
  • Start with POM; switch only when duplication/bloat forces it
They'll ask next · tap one for the answer
Copy link

What are the main types of performance testing?

Performance Testingmid

Load — expected traffic, does it hold up. Stress — past the limit, where and how does it break. Spike — a sudden surge, does it survive and recover.

Load — expected traffic, does it hold up. Stress — past the limit, where and how does it break. Spike — a sudden surge, does it survive and recover. Soak (endurance) — sustained load over hours, does it leak memory or degrade.

Each answers a different question: load proves the normal day, stress finds the ceiling, spike tests a launch or a sale, soak catches the slow leak that only shows after four hours. Naming which one a scenario needs is the tell that you've done this, not just read about it.

Key points
  • Load: expected traffic · Stress: past the limit
  • Spike: sudden surge + recovery · Soak: sustained, finds leaks
  • Pick the type by the question — ceiling, launch, or slow leak
They'll ask next · tap one for the answer
Copy link

Which performance metrics matter, and why not just the average response time?

Performance Testingsenior

Throughput (requests/sec), error rate under load, resource use (CPU, memory), and latency percentiles — p95 and p99, not the average.

Throughput (requests/sec), error rate under load, resource use (CPU, memory), and latency percentiles — p95 and p99, not the average. Averages hide the pain: a 200ms average can mean 5% of users wait 4 seconds, and those are often your highest-value sessions.

Saying "average response time" as your headline metric marks you as junior. The p99 is the experience of your worst-served real users, and it's where SLAs and lost customers live.

Key points
  • Throughput, error rate, resource use, latency percentiles
  • p95/p99 over average — averages hide the slow tail
  • 'Average response time' as the headline is a junior tell
They'll ask next · tap one for the answer
The trap

Leading with 'average response time' signals inexperience. Percentiles (p95/p99) are how performance is actually judged — the tail is the story.

Copy link

How do you structure a JMeter test plan?

Performance Testingmid

A Thread Group defines the virtual users and ramp-up. Inside it, Samplers make the requests (HTTP), Config Elements hold shared data (base URL, a CSV of test data), Assertions check responses stayed…

A Thread Group defines the virtual users and ramp-up. Inside it, Samplers make the requests (HTTP), Config Elements hold shared data (base URL, a CSV of test data), Assertions check responses stayed correct under load, and Listeners collect results. Timers add realistic think-time between requests.

The structure mirrors a real user session: ramp users up gradually (not all at once), feed each unique data so they're not hammering one record, assert that responses are still valid — a fast 500 is not a pass — and record percentiles, not just averages.

Key points
  • Thread Group (users + ramp) → Samplers → Assertions → Listeners
  • Config elements for shared data; timers for realistic think-time
  • Ramp gradually, feed unique data, assert correctness under load
They'll ask next · tap one for the answer
Copy link

How do you decide what load levels to test?

Performance Testingsenior

From real data, not a guess. Pull production traffic — peak concurrent users, requests per second, the busiest hour — and model the test on that, then add headroom (test at 1.5–2× peak) to prove…

From real data, not a guess. Pull production traffic — peak concurrent users, requests per second, the busiest hour — and model the test on that, then add headroom (test at 1.5–2× peak) to prove there's margin. For a launch with no history, estimate from marketing's expected numbers and test above them.

A load test at an arbitrary '1000 users' proves nothing if your real peak is 80 or 8000. The number has to trace back to reality, and the report should state which real scenario it represents.

Key points
  • Derive levels from production peaks, not a round number
  • Test above peak (1.5–2×) to prove headroom
  • Every load figure should trace to a real scenario
They'll ask next · tap one for the answer
Copy link

You ran a load test and response times are terrible. How do you find the bottleneck?

Performance Testingsenior

First rule out the test itself — an underpowered load generator or a slow network on the JMeter box looks exactly like a slow server.

First rule out the test itself — an underpowered load generator or a slow network on the JMeter box looks exactly like a slow server. Then correlate: watch server CPU, memory, DB, and thread pools while the load runs, and see which saturates first. The one that hits 100% while others are idle is your bottleneck.

Common culprits: the database (slow queries, missing index, connection pool exhausted), then CPU, then memory/GC. Observability during the run beats guessing — the metric that flatlines at its ceiling names the layer to fix.

Key points
  • Rule out the load generator/network first — it mimics a slow server
  • Correlate CPU/memory/DB/pools during the run; find what saturates
  • Usual suspect is the DB — slow queries, missing index, pool limits
They'll ask next · tap one for the answer
Copy link
They'll ask next