New · Cohort 4AI-Powered Data Engineering Cohort 4 goes live 26 September · only 40 seatsRegister Now
Interview Questions — ETL Testing

ETL Testing Interview Questions for 2026: Test Design, Validation SQL, and Answers That Hold Up

Sixteen interview questions covering what ETL testers are actually hired for — count, duplicate, referential and transformation checks, source-to-target mapping tests, SCD2 verification, defect classification, and reconciliation at scale. Written from the QA seat, not the pipeline-design seat.

By Durgesh Yadav — Senior Data Engineer @ 7-Eleven · Updated 29 Jul 2026. Preparation guidance, not a hiring guarantee.

Jump to 16 answered questionsBeginner to Advanced · 5 FAQs · 4-part guide

What questions are asked in an ETL testing interview?

ETL testing interviews focus on validation checks — row counts, duplicates, nulls, referential integrity, transformation rules — plus writing SQL to compare source and target, deriving test cases from a source-to-target mapping document, testing incremental loads and SCD Type 2 dimensions, classifying defects correctly, and reconciling large tables where row-by-row comparison is impractical.

Guide

What To Learn And How To Practice

What do ETL testing interviewers actually measure?

ETL testing interviews are SQL interviews wearing a QA hat. The interviewer wants evidence of three things. First, that you can turn a source-to-target mapping document into a concrete test suite — most candidates can name "count check, duplicate check" but stall when handed an actual mapping sheet and asked what they would test first. Second, that you can write the validation SQL live: orphan checks with LEFT JOIN, duplicate detection with GROUP BY and HAVING, both directions of EXCEPT, and window functions for SCD history. Third — and this separates 2-6-year candidates from freshers — judgment: what you check at 500 million rows when row-by-row comparison is off the table, how you classify a defect so it reaches the right owner, and how you regression-test a change without reloading the world. Note the difference from data engineering rounds: those probe pipeline design (CDC, idempotency, orchestration); ETL testing rounds probe verification of someone else's pipeline.

Deriving test cases from a mapping document, live
Validation SQL written from memory, not described
Scale judgment: what replaces row-by-row at 500M rows
Verification mindset — distinct from pipeline-design rounds

How should you prepare for an ETL testing round?

Build a two-table sandbox — any two schemas in Postgres or MySQL will do — and practice the whole loop: write a small mapping sheet, load "source" into "target" with a deliberate bug, then catch it with SQL. Drill the six core check patterns until they are muscle memory: counts per partition, duplicates on a business key, null checks on mandatory columns, orphan checks, EXCEPT in both directions, and independent recomputation of one derived column. Then rehearse the scenario layer: list the delta-load cases (insert, update, delete, boundary timestamp, rerun) and the SCD2 structural checks, because those get asked as "how would you test this" rather than "write the query". Finally, prepare defect stories from real work — one per category: a source-data issue, a spec ambiguity, a genuine code bug, an environment problem. Experienced candidates are judged more on those stories and their classification instincts than on syntax.

Two-table sandbox: seed a bug, catch it with SQL
Six check patterns drilled to muscle memory
Delta-load and SCD2 scenarios rehearsed verbally
One real defect story per taxonomy category

Which habits sink ETL testing candidates?

The most common failure is trusting counts: declaring a load verified because source and target row counts match, with no answer for truncation, wrong-row updates, or offsetting duplicate-and-missing errors. Second: tool recitation without SQL — naming testing tools you have used but freezing when asked to write the orphan check those tools generate. Third: running EXCEPT in one direction only, which finds missing rows but not invented ones, and forgetting that set operators collapse duplicates. Fourth: ignoring NULL semantics — candidates who do not know that NULL = NULL is false in a join predicate but NULLs match in EXCEPT and GROUP BY will write checks that silently pass on broken data. Fifth: treating every discrepancy as a code bug; interviewers deliberately present source-data or spec defects to see whether you classify before you blame. Finally, testing only the happy path of incremental loads — no rerun case, no boundary timestamp, no delete handling — reads as someone who has never seen a pipeline fail.

Sign-off on counts alone
One-directional EXCEPT, duplicates invisible
NULL semantics guessed, not known
Every defect blamed on code

Manual SQL or tool-based testing — which do interviewers want?

Interviewers care about the method, not the license. Tools in the QuerySurge mould add scheduling, cross-database comparison, and reporting on top of the same primitives — counts, minus queries, aggregate profiles — so the strong answer describes the check in SQL first and the tool as automation of it. Saying "the tool validates it" without being able to write the underlying query is a red flag; the reverse — manual SQL plus a clear view of what you would automate and why — is a green one. The ELT shift matters here too: when transformation happens inside the warehouse, validation moves with it. Checks become SQL against staging and mart layers, and frameworks in the dbt-test style let developers ship assertions with the code. That raises, rather than removes, the value of an independent testing lens: dev-owned tests encode the developer's assumptions, and the classic QA questions — is the spec right, what about the reject path, what breaks at the boundary — still need someone to ask them.

Describe the check in SQL, then the tool as automation
"The tool handles it" is a red-flag answer
ELT moves validation into warehouse SQL
Dev-owned dbt-style tests are not independent verification

Question bank

16 interview questions with answers

Real questions from beginner to advanced, each with a concise model answer — practice them, then rehearse live in a mock interview. Every answer is open; collapse any you have already covered.

EasyWhat is ETL testing, and how does it differ from application testing?

ETL testing verifies that data extracted from source systems lands in the target complete, accurate, and transformed exactly as the mapping specifies. The expected result is not a screen or API response — it is the source data plus the mapping rules, so almost every test is a SQL query comparing two datasets. Three differences stand out: the test oracle is the source-to-target mapping document, not a UI spec; volume is a first-class concern, since a check that works on 1,000 rows may be useless on 100 million; and many defects are not code defects at all — bad source data, an ambiguous mapping rule, or a mis-sequenced job each produce wrong output with correct code. Deciding which of those you are looking at is part of the tester's job.

EasyWhat is a source-to-target mapping document, and how do you derive test cases from it?

A source-to-target mapping (STM) lists, for every target column: the source table and column, the data type on both sides, and the transformation rule — direct move, derived expression, lookup, default, or aggregation. It is the tester's primary requirement document. Derive tests rule by rule: direct moves get value comparisons; derived columns get an independent recomputation; lookups get a join to the reference table plus an orphan check; default rules get cases where the source is NULL or invalid. Then add table-level cases no single mapping row implies — counts, duplicates on the declared grain, referential integrity, and truncation checks where types differ. If the STM is ambiguous, that is itself a defect: raise it rather than coding tests around a guess.

EasyWhat core validation checks make up a baseline ETL test suite?

Six categories. Count checks: compare source counts — after the filters and joins the spec defines — to target counts, overall and per load date. Duplicate checks: group by the business key and flag keys appearing more than once. Null checks: mandatory columns hold no NULLs and defaulting rules fired. Referential integrity: every fact foreign key resolves to a dimension row, since most warehouses do not enforce constraints. Transformation checks: recompute derived columns independently and compare. Datatype and truncation checks: verify precision, length, and encoding survive the move — VARCHAR(100) into VARCHAR(50) silently truncates in some configurations and errors in others. Each category maps to a reusable SQL pattern interviewers often ask you to write live.

EasySource and target row counts match. Why is that not enough to sign off the load?

A matching count proves the same number of rows arrived — not that they are the right rows or hold the right values. Failure modes that still pass: values truncated or defaulted during load; a wrong join that drops some rows and duplicates others so the totals cancel out; updates applied to the wrong rows; character-set corruption; a transformation bug altering a derived column on every row. Counts are the cheapest check, so run them first — but sign-off needs content validation: duplicate checks on the key, column aggregates (SUM, MIN/MAX, distinct and null counts) compared between source and target, MINUS/EXCEPT on manageable volumes, and independent recomputation of transformed columns. The summary interviewers want: counts prove completeness of volume, not correctness of content.

EasyWhich SQL constructs does an ETL tester rely on most, and why?

Five families cover most of the job. Joins — especially LEFT JOIN with WHERE right_key IS NULL, the standard orphan and missing-row pattern. Aggregation — duplicate detection via GROUP BY key HAVING COUNT(*) > 1, plus column profiling with SUM, MIN/MAX, COUNT(DISTINCT), and null counts. Set operators — MINUS/EXCEPT run in both directions to find rows present on only one side. Window functions — ROW_NUMBER to inspect duplicate groups or pick the latest record, LAG/LEAD to test SCD date-range continuity. CASE expressions — to recompute mapping rules independently instead of re-running the developer's logic. Underpinning everything: NULL = NULL is not true in a WHERE clause, yet set operators treat NULLs as matching and COUNT(column) skips them — forget this and checks false-pass.

MediumHow do you test for duplicate records, and how do you decide whether the defect is in the load or the source?

Start by pinning down the grain — "duplicate" is meaningless until you know what one row represents. For business-key duplicates:

sql
SELECT key_cols, COUNT(*)
FROM target
GROUP BY key_cols
HAVING COUNT(*) > 1;

For full-row duplicates, group by all columns or compare COUNT(*) against a distinct row-hash count. To inspect offenders, use ROW_NUMBER() OVER (PARTITION BY key ORDER BY load_ts DESC) — this also shows which copy the dedup logic should have kept. Then run the same check on the source: if the duplicate exists upstream, it is a source-data defect, and the question becomes whether the spec says dedupe, reject, or pass through. If the source is clean, suspect the load — a rerun without idempotency or a join that fans out are the usual causes.

MediumExplain the MINUS/EXCEPT comparison strategy and its limitations.

The pattern:

sql
(SELECT cols FROM source_query)
EXCEPT
(SELECT cols FROM target_query)

Then run it in the reverse direction too, because EXCEPT is asymmetric — one way finds rows missing from the target, the other finds rows the target invented. EXCEPT is set-based and collapses duplicates: three copies in source versus one in target shows no difference, so pair it with count and duplicate checks. NULLs compare as equal in set operations, unlike in join predicates. Formatting noise — trailing spaces, decimal precision, timestamp truncation — creates false diffs, so cast and trim deliberately. And it is expensive at volume and cannot span two engines natively; land both sides in one engine or use a comparison tool. Treat EXCEPT as drill-down, not the primary check on huge tables.

MediumHow do you test referential integrity when the target warehouse does not enforce foreign keys?

Most analytical databases accept foreign-key declarations but do not enforce them, so referential integrity is the tester's job. The core query: SELECT f.* FROM fact f LEFT JOIN dim d ON f.dim_key = d.dim_key WHERE d.dim_key IS NULL — any rows returned are orphans. Run it for every fact-to-dimension relationship, per load rather than once. Then test the stated failure policy: many pipelines route unresolvable keys to a default "unknown" member (often key -1) instead of dropping the row, so verify orphans actually land there and rows are not silently discarded. Late-arriving dimensions are the subtle case: a fact can legitimately arrive before its dimension row, so find out whether the spec says hold, default-and-reprocess, or reject — and write a test for that behavior, not just the happy path.

MediumHow do you validate complex transformation logic without trusting the developer's code?

The principle is independent recomputation: derive the expected value from the source yourself, using the mapping document, instead of re-running the developer's transformation — otherwise you are testing the code against itself. For a rule like "status = A if balance is positive and the account is open, else I", write your own CASE expression over source columns and compare it to the target column. For rules too complex to inline, build a small handcrafted dataset with a worked expected output covering every branch and boundary, run it through the pipeline in a test environment, and diff. Prioritize by risk: amounts, keys, and status fields get full-volume checks; descriptive text is sampled. Record which STM rule each test covers so coverage stays auditable against the spec.

MediumHow do you design test cases for an incremental (delta) load?

Design cases around every way a delta can behave, not just new rows. Inserts: a new source row appears exactly once. Updates: the changed row is updated (or versioned under SCD2) and nothing else is touched. Deletes: know whether the spec says hard delete, soft-delete flag, or ignore, and test that behavior explicitly. Unchanged rows: confirm they are not rewritten — counts will not reveal this; compare audit timestamps. Boundaries: a record timestamped exactly at the watermark, where > versus >= either drops or double-processes it. Rerun: execute the same window twice and verify the target is unchanged. Late data: an old event timestamp arriving after its window closed. Seed each case deliberately in a test environment — waiting for production data to cover these paths is not a strategy.

MediumAs a tester, how do you verify an SCD Type 2 dimension load?

Use structural queries, not eyeballing. One current version per key: assert each business key has exactly one current-flagged row, catching duplicated and missing current rows alike. No overlaps or gaps: with LAG, compare each row's effective start to the prior row's effective end per key; overlaps double-count facts at join time, gaps drop them. Change detection: update a tracked attribute in the source, run the load, and verify a new version appears, the old one closes with the correct end date, and the current flag moves. Then change a non-tracked attribute and verify no new version is created — over-triggering silently explodes the dimension. Finally, rerun the same load and confirm version counts are stable — all of it reusable SQL that belongs in every regression run of a dimension load.

MediumHow do you classify ETL defects, and why does the taxonomy matter?

Classify by what has to change to fix it. Source-data defects: the pipeline behaved correctly on bad input (duplicates, invalid dates, broken encodings upstream); the fix sits with the data owner — the pipeline question is whether the row should have been rejected or quarantined. Mapping defects: the STM is wrong, ambiguous, or contradicts source reality — the code faithfully implements a wrong rule. Code defects: output disagrees with an unambiguous STM. Environment defects: wrong connection, partial file pickup, mis-sequenced jobs. Performance defects: correct output, unacceptable load window. The taxonomy routes fixes to the right owner, stops developers "fixing" code to match bad data, and trending it shows where effort belongs — many spec defects signal a requirements problem, not a coding one.

HardA transformation is being changed. How do you regression-test the pipeline without reloading everything?

The goal is proving the change altered only what it was meant to alter. Impact analysis first: from the changed mapping or code, list affected target tables and columns; scope is those plus everything downstream. Then a baseline diff: run old and new logic against the same frozen input and compare outputs — full EXCEPT on modest volumes, column aggregates and row-hash comparisons at scale. Every difference must be explainable by the change request; unexplained diffs are defects. Alongside that, keep a standing suite of assertion queries — counts, duplicates, referential integrity, SCD structure — versioned and run on every release, so the checks that caught last year's defects keep running. The trap to name explicitly: regression-testing only the changed table and missing fan-out effects downstream.

HardThe table has 500 million rows and row-by-row comparison is infeasible. How do you reconcile source and target?

Tier the comparison so expensive checks run only where cheap ones fail. Tier one: row counts per partition — load date, region, source system — which localizes any discrepancy immediately. Tier two: column profiles compared source versus target — SUM and MIN/MAX on numerics, COUNT(DISTINCT) on keys, null counts per column. These are single-pass aggregations even at this scale, and a mismatch names the column and partition to chase. Tier three: hashed buckets — hash each row, bucket by key (MOD of a key hash into 1,024 buckets), aggregate hashes per bucket on both sides, and run row-level EXCEPT only on mismatched buckets. Two cautions: hashing must be deterministic across engines, so cast and format consistently first, and reconcile against a consistent snapshot, or in-flight loads create false diffs.

HardHow do you build and maintain test data for ETL testing?

Two sources, two jobs. Masked production subsets give realistic distributions and the messiness synthetic generators miss — but subsetting must be referentially consistent: pull the parent rows for every sampled child, or you manufacture fake orphan defects. Masking must happen before data reaches the test environment and must preserve formats, key uniqueness, and joinability, or half the suite breaks. Synthetic data covers what production lacks: NULLs in every nullable column, max-length strings, invalid values for the reject path, duplicate keys, a record timestamped exactly at the load watermark. Keep synthetic cases versioned with worked expected outputs so they double as regression fixtures. The interview-worthy line: production copies find unknown defects; synthetic data proves known risks are handled.

HardIf you were to automate ETL testing, what would the framework need?

Five things. Assertions as code: every check — counts, duplicates, referential integrity, recomputed transformations, SCD structure — is a versioned SQL query with a machine-readable pass condition, not a spreadsheet run by hand. An execution harness: tools in the QuerySurge mould do scheduled cross-database comparison; a pytest- or dbt-test-style runner querying both systems is the lightweight equivalent. Tolerances and severity: some checks hard-fail the pipeline (duplicate keys), others warn within a threshold — encoding that judgment is most of the design work. Integration: run in CI on code changes and post-load in production, so regression and monitoring share one suite. History: persist results per run — a metric drifting toward its threshold is a signal no single run shows. Tools vary; these requirements do not.

FAQ

Common Questions

Is ETL testing still a good career in 2026 with ELT and dbt?

The work is shifting shape, not disappearing. As transformation moves into the warehouse, validation becomes SQL-first and increasingly automated, and pure manual-execution roles are shrinking. But demand for people who can design data validation — at services companies, GCCs running large migration programs, and product teams building pipelines — remains real. The strongest position is ETL testing skill plus automation: assertion suites running in CI, not spreadsheets of manually run queries. Migration and modernization projects in particular hire heavily for this.

How much SQL do I need for an ETL testing interview?

More than most candidates expect. You should write, without references: multi-table joins including the LEFT JOIN orphan pattern, GROUP BY with HAVING for duplicates, set operators (MINUS/EXCEPT) with their direction and duplicate caveats, aggregate profiling with SUM, COUNT DISTINCT and null counts, and window functions — ROW_NUMBER for duplicate inspection, LAG for SCD date-range checks. NULL semantics come up constantly. Expect at least one live query round; describing checks verbally without writing them usually is not enough.

Do I need experience with a specific ETL testing tool?

Rarely as a hard requirement. Job posts list tools, but interviews test transferable method: what to check, in what order, and the SQL that does it. If you know a commercial comparison tool in the QuerySurge mould, or have built a homegrown SQL harness, present it as automation of checks you can also do manually. A candidate who writes clean validation SQL but has not used the team's specific tool beats one who knows the tool's menus but cannot write the orphan check underneath.

How is ETL testing different from database testing?

Database testing validates one system: schema, constraints, stored procedures, CRUD behavior, transactions. ETL testing validates movement and transformation between systems: did every source row arrive, were the mapping rules applied correctly, do keys still resolve, did types and precision survive the move. The test oracle differs too — database tests check behavior against a functional spec; ETL tests check target data against source data plus mapping rules. ETL testing also carries volume and cross-engine comparison problems that single-database testing never meets.

What is expected from freshers versus experienced candidates?

Freshers are tested on fundamentals: the core check types, clean SQL for each, NULL handling, and the ability to read a mapping document. At 2-6 years, interviewers add judgment: real defect stories with correct classification, delta-load and SCD2 test design, regression strategy for changes, reconciliation at scale, and automation experience. Experienced candidates who answer with fresher-level material — definitions and check lists without war stories or scale thinking — get marked down hardest, because the gap between resume and depth is obvious.

Next Step

Turn The Guide Into Practice

Use PrepNPlaced tools to turn this learning path into resume proof, targeted practice, and interview-ready explanations.

Practice AI Mock Interview