QA Interview
SDET Coding Interview Questions for Testers (2026)
Practice SDET coding interview questions testers face in 2026 with runnable Python, algorithms, SQL, async testing, edge cases, and credible model answers.
30 min read | 3,170 words
TL;DR
SDET coding interviews reward correct, readable problem solving plus a tester's verification discipline. Master core data structures, parsing, state, SQL, and async behavior, then practice clarifying assumptions, coding a simple solution, testing edge cases, and explaining tradeoffs aloud.
Key Takeaways
- Treat every coding prompt as a contract clarification, implementation, verification, and communication exercise.
- Prioritize strings, arrays, maps, sets, stacks, queues, intervals, parsing, trees, and practical asynchronous behavior.
- Choose data structures from required operations and constraints, then state time and space complexity precisely.
- Write normal, boundary, adversarial, and regression checks before calling a solution complete.
- Connect algorithms to logs, payloads, retries, event streams, test data, selectors, and framework utilities.
- Prefer pure functions and explicit dependencies because deterministic code is easier to test and explain.
- Practice in the language allowed for the target role and compile or run every solution under interview-like limits.
SDET coding interview questions testers receive are designed to reveal two related skills: can you write maintainable software, and can you prove that it behaves correctly? A strong solution clarifies the contract, chooses a suitable data structure, handles invalid and boundary input, runs verification cases, states complexity, and connects the technique to real automation work.
This guide is language-aware but not language-exclusive. Runnable examples use the Python standard library so you can practice without a framework setup. If the job requires Java, JavaScript, TypeScript, C#, or another language, implement the same patterns there and learn its collection, error, concurrency, and testing idioms. Do not switch languages merely because one example looks shorter.
TL;DR
| Phase | What to say or do | Signal to the interviewer |
|---|---|---|
| Clarify | Define input, output, constraints, and errors | You solve the requested problem |
| Design | State a direct approach and data structure | Your choices are deliberate |
| Implement | Write small, readable units | You can maintain production code |
| Verify | Run normal, boundary, and adversarial cases | You think like a tester |
| Analyze | State time and space complexity | You understand scale |
| Improve | Discuss alternatives only when useful | You can evaluate tradeoffs |
| Apply | Connect the pattern to test engineering | You build practical automation |
Use the loop clarify -> example -> algorithm -> code -> verify -> complexity -> follow-up. Repeat it until it feels natural under a timer.
1. What SDET coding interview questions testers actually measure
Most SDET coding rounds are not competitive-programming contests. Interviewers often want to know whether you can build framework utilities, reason about service data, debug automation, and collaborate through code. A problem about character counts may reveal how you handle input contracts, naming, data structures, tests, and complexity.
Start by restating the prompt. Ask whether comparison is case-sensitive, whether order matters, what happens with None or null, whether duplicates are meaningful, how large input can be, and whether mutation is allowed. Ask only questions that affect the design. If the interviewer leaves a choice open, state your assumption and proceed.
Use a small example before coding. For "find duplicate IDs," write a normal list, no-duplicate list, empty list, and repeated duplicate. This exposes whether output should preserve first-seen order and whether each duplicate appears once or multiple times. It also gives you immediate verification input.
Prefer the simplest approach that meets constraints. A clear O(n) map solution is usually better than a compact expression you cannot explain. Brute force can be a reasonable starting point when you state its cost and then improve it. Do not optimize without knowing the scale or required operations.
Finally, narrate without reading every keystroke. Explain decisions, call out a discovered error, fix it, and run tests. Interviewers do not require flawless first-pass typing. They do require evidence that you can reason and recover.
2. Build a focused preparation map
Organize practice by patterns, not by memorized company questions. The same map or queue idea appears in logs, API payloads, browser events, and algorithm prompts. A focused sequence creates transfer.
| Pattern | Representative problem | SDET application | Key follow-up |
|---|---|---|---|
| String scan | Normalize or count tokens | Log signatures and selectors | Unicode and case policy |
| Map or set | Frequency and duplicates | Compare IDs across systems | Order and memory |
| Two pointers | Filter or pair search | Ordered result comparison | Sorted-input assumption |
| Stack | Balanced delimiters | Validate templates or expressions | Error location |
| Queue | Breadth-first traversal | Event and job scheduling | Capacity and fairness |
| Intervals | Merge or detect overlap | Outage and execution windows | Boundary convention |
| Tree or graph | Traverse dependencies | Page, service, or test relationships | Cycles and visited state |
| Parsing | Transform records safely | API, CSV, and log validation | Invalid or missing fields |
| Async control | Bound parallel work | API setup and suite execution | Timeout and cancellation |
| SQL | Aggregate and reconcile | Database validation | Duplicates and NULL |
Spend more time on implementation and explanation than passive reading. For each pattern, solve one easy and two medium exercises, then adapt one to a testing use case. Revisit the same problem after several days without looking at the prior answer.
If your target stack is Java, use the Java coding interview questions for testers guide for collections, streams, exceptions, and concurrency idioms. For JavaScript or TypeScript roles, review async and await in tests and practice promise error handling rather than only array puzzles.
3. Strings, arrays, and two-pointer reasoning
String questions often hide contract decisions. Is a string a sequence of bytes, code points, or user-perceived characters? Should punctuation, case, and whitespace matter? A tester should surface these assumptions. In many interviews, the expected scope is simple ASCII or language-native iteration, but say so.
Practice reversal, palindrome checks, first unique character, frequency counts, longest common prefix, substring windows, tokenization, and normalization. For arrays, practice compaction, pair sums, sliding windows, rotation, missing values, and comparison. Two pointers are useful when the input is sorted or when scanning from both ends avoids extra storage. Do not use the pattern if it makes the code less clear.
A practical exercise is to normalize an error message into a stable signature. Dynamic request IDs and extra whitespace can make equivalent failures look different. The contract matters because excessive normalization can collapse distinct defects.
import re
def error_signature(message: str) -> str:
if not isinstance(message, str):
raise TypeError("message must be a string")
without_ids = re.sub(r"request_id=[A-Za-z0-9-]+", "request_id=<id>", message)
return " ".join(without_ids.lower().split())
def test_error_signature() -> None:
first = "Timeout request_id=abc-123 while reading"
second = "TIMEOUT request_id=xyz-999 while reading"
assert error_signature(first) == error_signature(second)
assert error_signature(" permission denied ") == "permission denied"
if __name__ == "__main__":
test_error_signature()
print("signature checks passed")
This runs in O(n) time relative to message length and returns a new string. Follow-ups include Unicode case normalization, multiple identifier formats, redaction, and preserving meaningful numbers such as status codes. Explain that regex patterns should come from known log contracts, not a broad guess that hides defects.
4. Maps, sets, counting, and reconciliation
Maps answer "how many" or "which value belongs to this key." Sets answer "have I seen this" or "what is the unique membership." Practice frequency maps, duplicate detection, grouping, intersections, anagrams, first unique items, and joining records by ID.
Choose the variant deliberately. A regular dictionary preserves insertion order in current Python, but an interview in another language may require a linked map. A set loses duplicates and often order. A multiset or counter retains counts. If the output must explain every occurrence, converting to a set too early destroys evidence.
Reconciliation is an SDET-rich application. Suppose an API returns order IDs and the database contains persisted records. Compute missing in database, unexpected in database, and duplicates within each source. Do not compare only counts because equal totals can hide different members.
from collections import Counter
def reconcile(expected: list[str], actual: list[str]) -> dict[str, list[str]]:
expected_counts = Counter(expected)
actual_counts = Counter(actual)
return {
"missing": sorted((expected_counts - actual_counts).elements()),
"unexpected": sorted((actual_counts - expected_counts).elements()),
"duplicate_expected": sorted(
key for key, count in expected_counts.items() if count > 1
),
"duplicate_actual": sorted(
key for key, count in actual_counts.items() if count > 1
),
}
def test_reconcile() -> None:
result = reconcile(["a", "b", "b", "c"], ["a", "b", "d", "d"])
assert result == {
"missing": ["b", "c"],
"unexpected": ["d", "d"],
"duplicate_expected": ["b"],
"duplicate_actual": ["d"],
}
if __name__ == "__main__":
test_reconcile()
print("reconciliation checks passed")
The expected time is O(n + m + k log k) here because results are sorted, and space is O(n + m) in the worst case. Ask whether deterministic output order is required. If not, sorting can be removed.
5. Stacks, queues, intervals, trees, and graphs
A stack matches nested structure and last-in-first-out work. Practice balanced brackets, expression validation, path normalization, and undo-like state. Improve a boolean bracket checker by returning the invalid position and expected token. Test empty input, wrong closer, missing closer, unrelated characters, and deep nesting.
A queue supports first-in-first-out processing and breadth-first search. Practice level-order tree traversal, shortest unweighted path, and bounded job queues. In test infrastructure, queue questions lead naturally to fairness, capacity, cancellation, poison jobs, and retry policy. State whether enqueue and dequeue need thread safety.
Intervals appear in test scheduling, availability, traces, and outage reports. Clarify whether intervals are closed, open, or half-open. For half-open intervals [start, end), [1, 3) and [3, 5) do not overlap, although a business rule may still choose to merge adjacent windows. Sort by start, then extend the last merged interval when overlap is detected.
Trees model DOM or comment structure. Graphs model service dependencies, workflow states, and test prerequisites. Practice depth-first and breadth-first traversal, cycle detection, reachable nodes, and topological ordering. Always track visited nodes in a graph that can cycle. Recursive solutions can overflow on deep input, so discuss an iterative option when scale matters.
For an automation scenario, imagine selecting all services affected by a dependency failure. Graph traversal finds reachability, but the result alone does not prove impact. Edge type, fallback, cache, and runtime state matter. This is an excellent moment to distinguish the algorithm's contract from a production conclusion.
6. Parsing structured input and designing test data
Parsing questions are common because SDETs consume JSON, CSV, XML, logs, environment variables, and command output. A reliable parser validates types, required fields, optional defaults, unknown values, encoding, size, and error context. It does not silently convert every malformed record into an empty object.
Use a two-step design: parse syntax, then validate domain semantics. Valid JSON can still contain a negative quantity, unknown status, duplicate identifier, or timestamp in the wrong relationship. Keep these failures distinguishable so diagnostics are useful.
Practice transforming a list of API records into a map by ID. Ask what should happen with duplicate IDs. Last-write-wins is easy but can hide corruption. Rejecting duplicates or collecting all versions may be better. Test missing ID, null, wrong type, unknown field, empty collection, maximum size, and a record at the boundary.
Test data builders should make valid defaults easy and differences visible. Prefer valid_order(quantity=...) over fixtures with twenty positional fields. Builders must not hide required business decisions or share mutable objects between tests. Seed random generators and print the seed on failure.
Property-based testing can generate broader input, but it does not replace a precise oracle. Define properties such as normalization idempotence, sort-order preservation, decode-encode round trip under the contract, or result membership. Preserve the minimized failing example. In an interview, explain the property even if the environment does not include a property-testing package.
7. Async code, retries, timeouts, and concurrency
Modern automation spends much of its time waiting for browsers, services, queues, or files. Async coding questions test whether you understand completion and failure, not just syntax. Prepare sequential versus concurrent execution, bounded concurrency, exception propagation, cancellation, timeouts, and cleanup.
A retry function needs a contract. Which errors are transient? Is the operation idempotent? How many attempts, what delay policy, what total deadline, and what evidence is retained? Never retry assertion failures or all exceptions by default. A timeout should bound the operation and cancel or isolate late work where supported.
Python's asyncio.TaskGroup provides structured concurrency in supported modern Python versions. If one child fails, remaining tasks are canceled and failures are raised as an exception group. The following example is runnable as python async_checks.py.
import asyncio
async def fetch_value(value: int, delay: float) -> int:
await asyncio.sleep(delay)
return value
async def collect() -> list[int]:
tasks: list[asyncio.Task[int]] = []
async with asyncio.TaskGroup() as group:
tasks.append(group.create_task(fetch_value(2, 0.02)))
tasks.append(group.create_task(fetch_value(1, 0.01)))
return [task.result() for task in tasks]
async def main() -> None:
result = await asyncio.wait_for(collect(), timeout=1.0)
assert result == [2, 1]
print("async checks passed")
if __name__ == "__main__":
asyncio.run(main())
Notice that result order follows task-list order, not completion order. An interview follow-up may ask for completion order, a concurrency limit, or partial results. State the desired semantics before changing code. Shared mutable state still requires synchronization even in cooperative concurrency.
8. SQL and API data questions
SDETs often need SQL for setup, validation, diagnosis, and reconciliation. Prepare filtering, joins, grouping, HAVING, subqueries or common table expressions, window functions, ordering, and transaction basics. Understand how NULL affects comparison and aggregation. Avoid changing shared data casually during an interview exercise.
A common question asks for duplicate event identifiers:
SELECT event_id, COUNT(*) AS occurrence_count
FROM delivery_events
GROUP BY event_id
HAVING COUNT(*) > 1
ORDER BY event_id;
This is valid on widely used relational databases and SQLite when the table exists. It identifies duplicate keys but does not prove duplicate business effects. Join or reconcile against the consumer's state to answer that question. Add a time range for a large production-like table, use approved read access, and inspect the query plan when performance matters.
Another pattern is "latest row per entity." A window function such as ROW_NUMBER() OVER (PARTITION BY entity_id ORDER BY event_time DESC, sequence DESC) can rank candidates, but tie-breaking must be deterministic. Ask whether event time or ingestion time defines latest.
For APIs, practice parsing status, headers, and JSON, then validating business state. Cover non-success responses, invalid JSON, absent fields, unknown enums, pagination, rate limiting, and timeouts. The API pagination testing guide connects common coding patterns to real boundary cases.
Keep SQL assertions readable. Fetch the smallest safe dataset, map rows to named fields, and report useful diffs. A test that dumps ten thousand rows without identifying the mismatch is hard to debug.
9. Write code that is easy to test and review
Interview code should expose its dependencies. A function that reads the current time, environment, network, and global cache internally is difficult to verify. Pass a clock, client, or data source when the problem benefits from control. Do not overbuild dependency injection for a ten-line algorithm, but name the production concern.
Prefer pure transformations for parsing, filtering, comparison, and expected-result calculation. Keep I/O at the boundary. This enables small deterministic tests and makes concurrency safer. Validate input at the appropriate layer and raise specific errors with context.
When asked to review code, examine correctness before style. Look for missing cases, mutation, resource leaks, race conditions, unchecked return values, swallowed exceptions, unstable ordering, insecure secrets, and misleading logs. Then discuss naming, decomposition, complexity, and maintainability.
Test code deserves production standards because it affects release decisions. Avoid page objects that become giant service locators, utility classes full of unrelated static methods, and helpers that catch every exception. Make failures actionable: expected state, actual state, relevant ID, elapsed time, and safe artifacts.
Explain tradeoffs without performing a full rewrite. "For this interview-sized input, a dictionary is clear and O(n). If input exceeds memory, I would stream and use an external store or sort, but that complexity is not justified by the stated constraint." This demonstrates scalability judgment without abandoning the problem.
10. SDET coding interview questions testers should practice in 30 days
Days 1 through 5: refresh language syntax, collections, functions, exceptions, and the test runner. Solve strings and arrays. For every solution, write at least four checks and state complexity. Compile or execute every file.
Days 6 through 10: practice maps, sets, counting, two pointers, and sliding windows. Turn two problems into log or API examples. Re-solve one earlier problem from memory. Review the core Java interview questions for Selenium testers if Java is required.
Days 11 through 15: practice stacks, queues, intervals, trees, and graph traversal. Add invalid-input behavior. Explain recursion limits and iterative alternatives. Do one forty-five-minute mock round in a plain editor.
Days 16 through 20: practice parsing, SQL, HTTP response handling, and data reconciliation. Create small fixtures with duplicates, missing fields, unknown values, and pagination boundaries. State the source of truth for each comparison.
Days 21 through 25: practice async completion, timeouts, bounded retries, cancellation, and shared-state hazards. Use a fake clock or dependency in one exercise. Review failures and remove arbitrary sleeps.
Days 26 through 30: alternate full mock interviews and review. Rotate coding, debugging, code review, and framework utility exercises. Record yourself, shorten vague explanations, and maintain an error notebook. On the final day, review patterns and language APIs, not dozens of new puzzles.
Interview Questions and Answers
Q: How do you find duplicates while preserving first duplicate order?
Use a seen set and a second set for values already emitted. Scan once, and append a value the first time it is encountered in seen but not in emitted. This is expected O(n) time and O(k) space.
Q: When would you use a map instead of a set?
Use a set for membership or uniqueness. Use a map when each key needs a count, associated record, position, or other value. State whether duplicate input should overwrite, accumulate, or fail.
Q: How do you test a palindrome function?
Clarify normalization first. Then cover empty, one character, odd and even length, non-palindrome, case, spaces or punctuation if included, and Unicode scope. Verify that input is not mutated unless allowed.
Q: What makes a retry helper safe?
It retries only classified transient failures on an idempotent or reconciled operation. It has bounded attempts and deadline, preserves the initial error, supports cancellation, and exposes metrics. Randomized delay may reduce synchronized retries in distributed use.
Q: How would you merge intervals?
Clarify boundary semantics, sort by start, and scan while comparing each interval with the last merged interval. Extend on overlap, otherwise append. Sorting makes time O(n log n), with O(n) output space.
Q: How do you compare API and database records?
Normalize only contractually equivalent fields, index both sources by stable key, detect duplicates, then report missing, unexpected, and field-level differences. Account for documented consistency delay and use the correct source of truth.
Q: What cases belong in a parser test?
Cover valid minimal and full input, empty input, missing required field, wrong type, unknown value, malformed syntax, duplicate key policy, encoding, and size boundary. Keep syntax and domain-validation failures distinguishable.
Q: How do you test async code deterministically?
Inject dependencies, clocks, and synchronization points. Await explicit completion rather than sleeping, bound waits, control response order, and assert cancellation and cleanup. Use stable seeds for randomized schedules.
Q: What is the difference between O(n) and O(n log n) in practice?
O notation describes growth, not exact runtime. A sort-based O(n log n) solution may be simpler or use less auxiliary structure than expected O(n) hashing. Choose based on constraints, order needs, memory, and input behavior.
Q: How do you handle NULL in SQL assertions?
Use IS NULL or IS NOT NULL, not equality with NULL. Understand how aggregates treat nulls and define whether missing, unknown, and empty are equivalent. Test those states explicitly.
Q: What do you do if your code fails an example during the interview?
Trace the smallest failing case, state the likely invariant violation, fix it, and rerun all cases. Explain the mistake briefly without becoming defensive. Recovery is useful evidence of debugging skill.
Q: How much should an SDET study algorithms?
Study enough to select and implement core data structures and common patterns confidently. Add parsing, SQL, async behavior, testing, and framework design because those often match the job more directly. Let the requisition determine extra depth.
The interviewQnA field below adds concise prompts for continued practice.
Common Mistakes
- Starting to code before clarifying output and invalid-input behavior.
- Memorizing solutions without understanding the data structure or invariant.
- Writing only the happy path and claiming tester strength verbally.
- Giving complexity for the main loop while ignoring sorting or nested work.
- Using a set when counts or duplicate evidence matter.
- Catching every exception and returning a value that hides failure.
- Retrying non-idempotent actions without reconciliation.
- Using sleeps to coordinate asynchronous code.
- Overengineering a small problem before producing a correct baseline.
- Failing to run or manually trace the final solution.
Conclusion
The best way to prepare for SDET coding interview questions testers face is deliberate, executable practice. Clarify each contract, choose a data structure from the needed operations, implement readable code, verify edge cases, state complexity, and connect the solution to a quality-engineering problem.
Use the 30-day plan, keep an error notebook, and work in the language required by the role. A candidate who can prove a simple solution and explain its limits will usually create more confidence than one who memorizes many clever answers.
Interview Questions and Answers
How would you find the first nonrepeating character?
I would clarify case and character semantics, then count characters in one pass and scan again for the first count of one. This is O(n) time and O(k) space. I would test empty, all repeated, first unique at each boundary, case differences, and the agreed Unicode scope.
How do you detect duplicates without losing evidence?
I use a frequency map when counts matter and a set only for membership. I define whether output should contain each duplicate once or every extra occurrence and whether order matters. Then I test repeated duplicates, empty input, and equal-but-different representations.
How would you validate balanced brackets?
I push opening tokens on a stack and require each closing token to match the top. At the end the stack must be empty. I test empty input, valid nesting, wrong closer, leading closer, missing closer, and unrelated-character policy.
How do you merge overlapping intervals?
I first define open, closed, or half-open boundaries and whether adjacency merges. I sort by start and scan, extending the last result on overlap. The complexity is O(n log n) time due to sorting and O(n) output space.
How would you reconcile two lists of record IDs?
I count both sides by stable ID and compute missing, unexpected, and duplicate occurrences. I preserve deterministic output when diagnostics require it. Equal list lengths are not a sufficient oracle because members can differ.
What tests would you write for a retry function?
I cover immediate success, transient failures then success, attempt exhaustion, nonretryable error, deadline, cancellation, delay policy, and preserved root cause. I also verify the operation is idempotent or reconciled. I use a fake clock and scripted dependency instead of real sleeping.
How do you parse unreliable JSON input?
I separate syntax parsing from schema and domain validation. I check required fields, types, bounds, unknown enums, duplicates where relevant, and error context. I do not silently replace malformed input with defaults that create false passes.
How would you test a queue implementation?
I test FIFO order, empty behavior, one element, repeated enqueue and dequeue, capacity boundary if bounded, and invalid values. For concurrent use I add multiple producers and consumers, shutdown, cancellation, and no-loss or no-duplicate invariants.
What does deterministic async testing require?
It requires explicit completion conditions and control over dependencies, time, and key schedules. I await events or futures, bound timeouts, and assert cancellation and cleanup. I avoid arbitrary sleeps and print seeds for randomized schedules.
How do you find duplicate rows in SQL?
I group by the business key and filter groups with `HAVING COUNT(*) > 1`. I clarify whether null keys count and whether the key spans multiple columns. Then I inspect affected rows or reconcile their business effects rather than stopping at the count.
How would you review an automation utility?
I check correctness, input and error contracts, mutation, resource cleanup, concurrency, secret handling, logs, complexity, and tests before style. I look for swallowed exceptions and hidden global dependencies. I suggest the smallest change that makes behavior safer and more diagnosable.
How do you choose between breadth-first and depth-first traversal?
Breadth-first search fits shortest paths in unweighted graphs and level-order results, while depth-first search fits reachability, structure, and backtracking. Both need visited tracking for cyclic graphs. I also consider memory, recursion depth, and required output order.
What should you do when constraints are missing?
I ask the few questions that change the design, then state reasonable assumptions and proceed. I can offer a simple baseline and explain how different scale or memory constraints would change it. I avoid stalling while waiting for perfect requirements.
What distinguishes an SDET coding answer from a generic coding answer?
The core algorithm still must be correct, but an SDET should be unusually strong at contracts, edge cases, diagnostics, determinism, and proof. I connect the pattern to automation or system evidence without forcing the analogy. I also treat test code as production-quality decision software.
Frequently Asked Questions
Which coding topics should an SDET prepare?
Prioritize strings, arrays, maps, sets, stacks, queues, intervals, trees, graphs, parsing, SQL, and practical async behavior. Add language-specific collections, errors, concurrency, and test-framework knowledge from the job description.
Are SDET coding interviews as hard as software developer interviews?
Difficulty varies by company and role. SDET interviews often combine core coding with stronger expectations around verification, automation design, debugging, APIs, data, and system quality.
Which language should I use in an SDET coding interview?
Use an allowed language you can write, run, test, and explain confidently. Prefer the role's required language when practical, especially for framework or code-review exercises.
How many coding problems should I solve before an SDET interview?
There is no reliable magic number. Build coverage across core patterns, revisit problems without notes, and complete timed mocks with verification and explanation rather than chasing a large count.
Do SDET interviews include SQL questions?
Many data and service-oriented roles value SQL for validation and diagnosis, although not every loop includes it. Prepare joins, grouping, duplicates, nulls, windows, and reconciliation if the posting mentions databases or backend testing.
Should I write tests during a coding interview?
Yes, when the format permits. At minimum, state and manually trace normal, boundary, invalid, and adversarial cases, because verification is a central SDET signal.
How do I improve coding speed without sacrificing quality?
Practice a consistent sequence, learn standard-library APIs, use small helper functions, and reduce time lost to unclear contracts. Timed repetition with review is safer than skipping tests or compressing code.
Related Guides
- Python Coding Interview Questions for Testers (2026)
- Java Coding Interview Questions for Testers (2026)
- JavaScript Coding Interview Questions for Testers (2026)
- SQL Coding Interview Questions for Testers (2026)
- SQL Interview Questions for QA and Testers (2026)
- Agile Scrum Interview Questions for Testers