Source-to-Target Checks • Data Quality • Transformations • SCD & Incremental Loads • SQL for Testers • 2026

ETL Testing Interview Questions

30 questions What each one tests, an answer frame, a spoken answer 35 min read

This page is for testers preparing for an ETL or data warehouse testing round, whether it's your first data role or you've been validating loads for years. Most rounds start with what ETL testing is and how a mapping document becomes test cases, then move to completeness and accuracy checks, duplicates, nulls and orphan keys. After that come transformations, slowly changing dimensions, incremental loads and reruns, often with a request to write the SQL. Senior rounds add load performance, automation and judgement calls. Each question shows what the interviewer is checking, the shape of a strong answer and a sample you can say out loud. Practise them, then swap in your own stories.

Search all questions by round, difficulty and level, or save the ones you want to practise.

ETL Fundamentals 2 questions

Easy Technical round Fresher Practice question

1. What is ETL testing, and what kinds of checks does it cover that normal application testing doesn't?

What the interviewer is really testing:
Whether you see ETL testing as proving data is complete, correct and on time, rather than clicking through screens.
Answer frame:

What it is: checking that data extracted from sources, transformed by the rules and loaded into the target arrives complete and correct.

Main checks: metadata like types and lengths, counts and completeness, field-level accuracy, transformation rules, duplicates and nulls, referential integrity.

Beyond data: incremental and rerun behaviour, reject handling, load performance, and the reports built on top.

Sample spoken answer:

"ETL testing is about proving the data is right, not the screens. A job extracts data from one or more sources, transforms it by business rules, and loads it into a target, usually a warehouse. My job is to show nothing got lost, nothing got duplicated, and every value in the target is what the rules say it should be. So the checks are mostly SQL: row counts and totals between source and target, column-by-column comparisons, recomputing each transformation independently, and checking for duplicates, nulls and orphan keys. Then there's behaviour over time, which normal app testing rarely has: does the daily incremental load pick up only the changes, does a rerun create duplicates, do bad records go to a reject table instead of failing the whole job. And the load has to finish inside its window, so performance matters too."

Red flag to avoid:

Describing ETL testing as only checking that the job finished successfully, or only comparing row counts.

They may ask next:
  • Where in the pipeline would you start testing if you only had one day?
  • How is testing a report built on the warehouse different from testing the load itself?
Say it in 60 seconds
Medium Technical round Mid-level, Senior Practice question

2. If your team switches from ETL to ELT, what changes about where and how you test?

What the interviewer is really testing:
Whether you understand where transformations run in each pattern, and can move your checks to follow them.
Answer frame:

The difference: ETL transforms in a separate engine before loading; ELT loads raw data first and transforms inside the warehouse.

New test points: check the raw landed layer against the source, then test each transformation step as SQL in the warehouse.

What stays: reconciliation from source to final tables, rules, duplicates, and the reports on top.

Sample spoken answer:

"In classic ETL the transformation happens in a separate engine, between source and target, so I mostly test from the outside: compare the source with the final tables and check the rejects. In ELT the raw data lands in the warehouse first, pretty much untouched, and the transformations run as SQL inside the warehouse. That changes two things for me. First, I get a new checkpoint: I can reconcile the raw layer against the source on its own, so if a number is wrong later I know it wasn't the extract. Second, the transformation logic is usually SQL in version control, so I can read it, review it, and run checks after each step, like uniqueness and not-null tests, as part of the same pipeline. What doesn't change is the end-to-end reconciliation. The business still cares that the final numbers match the source."

Red flag to avoid:

Saying ELT needs less testing because the warehouse handles everything.

They may ask next:
  • Where would you put automated checks in an ELT pipeline so one bad step doesn't feed the next one?
  • What extra risk does keeping raw data in the warehouse add for a tester?
Say it in 60 seconds

Source-to-Target Checks 5 questions

Easy Technical round Fresher, Mid-level Practice question

3. What is a source-to-target mapping document, and how do you turn it into test cases?

What the interviewer is really testing:
Whether you can work from the mapping as your specification and derive concrete, checkable cases from each line.
Answer frame:

What it holds: for each target column, the source table and column, the rule, data types, and defaults for nulls.

Test cases: one or more cases per mapping line, plus table-level cases for counts, keys and filters.

Gaps: questions for the analyst wherever a rule is vague or a column has no source.

Sample spoken answer:

"The mapping document is the spec for an ETL job. For every target column it says where the data comes from, which source table and column, what rule is applied, like a trim, a lookup or a calculation, the data types on both sides, and what happens when the source is null. It also usually lists the join conditions and filters, like 'only active accounts'. I turn it into tests in two layers. At the table level I write cases for row counts, the filter rules and key uniqueness. Then I go line by line: a straight move gets a direct compare, a derived column gets a query that recomputes the rule from the source, and a lookup gets a check for the not-found case. While doing that I mark every rule that's ambiguous and take those questions to the analyst before testing starts, because that's where most defects hide."

Red flag to avoid:

Treating the mapping as optional and testing only what the developer says the job does.

They may ask next:
  • What do you do when the mapping and the developer's code disagree?
  • How do you keep track of which mapping lines your tests cover?
Say it in 60 seconds
Medium Technical round Fresher, Mid-level Practice question

4. How do you prove that every record from the source actually made it to the target?

What the interviewer is really testing:
Whether you check completeness beyond a single row count, accounting for filters, rejects and keys.
Answer frame:

Counts that balance: source rows in scope equal loaded plus rejected plus intentionally filtered.

Keys: compare the set of business keys on both sides to find exactly which records are missing or extra.

Slices: break counts down by day, region or type so a gap in one slice isn't hidden by an excess in another.

Sample spoken answer:

"I start with counts, but I make them balance, not just match. The source count for the extract window should equal what loaded, plus what went to the reject table, plus what the rules deliberately filter out, like test accounts. If that doesn't add up, something vanished silently. Then I compare keys, not just totals: I pull the business keys from both sides and find which ones are in the source but not the target, and the other way round. That tells me exactly which records to chase. I also break the counts down by something like load date or region, because a total can match by accident when one slice is short and another has duplicates. And I check the extract window itself, because records created right at the boundary time are the ones that most often fall between two runs."

Red flag to avoid:

Saying a matching row count proves the load is complete.

They may ask next:
  • Counts match, but a business user says a customer is missing. How is that possible?
  • How would you do this when source and target sit in different databases?
Say it in 60 seconds
Medium Technical round Mid-level Practice question

5. Row counts match between source and target. Why isn't that enough, and how do checksum or aggregate checks help?

What the interviewer is really testing:
Whether you know counts only prove quantity, and can verify content cheaply before doing a full row-by-row compare.
Answer frame:

Why counts fail: a row can arrive with wrong values, and a missing row plus a duplicate still gives the same count.

Aggregates: compare sums of amounts, distinct key counts, and min and max dates on both sides.

Hashes: hash each row's columns in a fixed format to spot changed rows, then drill into the ones that differ.

Sample spoken answer:

"A count only tells me how many rows arrived, not what's in them. If one row is dropped and another is duplicated, the count still matches. And a row can arrive with an amount rounded wrong or a date shifted by a day. So next I compare aggregates for the same slice on both sides: the sum of the amount columns, the count of distinct keys, and the min and max of the dates. If the sums differ, I know there's a value problem, even with equal counts. For a stronger check I hash each row: join the mapped columns with a delimiter, turn nulls into a fixed marker, format dates and decimals the same way on both sides, then compare the hash per key. Rows with different hashes are exactly the ones to inspect. The formatting step matters, because trailing spaces or a different date format will change the hash even when the data is fine."

Code:
SELECT COUNT(*)                 AS row_count,
       COUNT(DISTINCT order_id) AS distinct_orders,
       SUM(amount)              AS total_amount,
       MIN(order_date)          AS first_date,
       MAX(order_date)          AS last_date
FROM sales_target
WHERE load_date = '2026-09-01';
-- Run the same query on the source for the same slice and compare.
Red flag to avoid:

Trusting row counts alone, or hashing both sides without normalising nulls and formats first.

They may ask next:
  • Why do you put a delimiter between columns before hashing them?
  • Two different sets of rows can give the same sum. What would you add to catch that?
Say it in 60 seconds
Medium Coding round Fresher, Mid-level Practice question

6. Write the queries you'd use to find rows missing from the target, and rows in the target that don't match the source.

What the interviewer is really testing:
Whether you can write the standard two-way set comparison and know where it goes blind.
Answer frame:

Both directions: source minus target finds missing or changed rows; target minus source finds extra or changed rows.

Apply the rules: transform the source side, like trimming or upper-casing, so you compare like with like.

Blind spot: set operators work on distinct rows, so pair this with a duplicate check.

Sample spoken answer:

"I use a set difference in both directions. Source EXCEPT target gives rows that are missing in the target or arrived with different values. Target EXCEPT source gives rows the target has that the source doesn't, which catches extra rows and the changed version of the same records. Oracle has long used the keyword MINUS for the same thing. Two things make this reliable. First, if a column is transformed, I apply the same rule on the source side in the query, otherwise every row shows up as different. Second, EXCEPT works on distinct rows, so if the target has a record twice, this comparison won't show it. That's why I always pair it with a duplicate check on the business key. One helpful detail: set operators treat two nulls as equal, so nulls don't create false mismatches the way an equals join would."

Code:
-- In the source but missing or different in the target
SELECT customer_id, email, city FROM src_customer
EXCEPT
SELECT customer_id, email, city FROM tgt_customer;

-- In the target but not in the source: extra or changed rows
SELECT customer_id, email, city FROM tgt_customer
EXCEPT
SELECT customer_id, email, city FROM src_customer;
Red flag to avoid:

Only running the comparison in one direction, or not knowing that EXCEPT hides duplicates.

They may ask next:
  • Both queries return 300 rows. How do you tell missing rows from changed rows?
  • How would you run this if the tables have 200 million rows each?
Say it in 60 seconds
Hard Technical round Mid-level, Senior Practice question

7. Source and target are on different database platforms, with about 50 million rows. How do you compare them without pulling everything into a spreadsheet?

What the interviewer is really testing:
Whether you can design a comparison that scales, instead of relying on a join that can't run across two systems.
Answer frame:

Bucket first: compute counts, sums and hashes per day or key range on each side, and compare the small results.

Drill down: only the buckets that differ get a row-level comparison.

Or co-locate: copy the source extract into a staging area next to the target so a set comparison runs in one place.

Sample spoken answer:

"I can't join across two platforms directly, and I don't want to move 50 million rows around just to learn that everything matches. So I compare in layers. First, on each side I run a query that groups by a bucket, like load date or a range of the key, and returns the count, the sum of the key amounts, and an aggregated hash for each bucket. That's maybe a few hundred rows per side, easy to compare in a script. Then only the buckets that differ get a row-level comparison, which is small. If the team already lands a raw copy of the source in a staging schema next to the target, I use that and run the set comparison in one database. The trap is making the hash identical on both platforms: same column order, same null marker, same date and decimal formatting, and the same hash function, or everything looks different."

Red flag to avoid:

Proposing to export both tables to files and eyeball them, or checking a few sample rows and calling it done.

They may ask next:
  • How would you handle a column that is a float on one side and a fixed decimal on the other?
  • Would you ever settle for a sample instead of a full compare? When?
Say it in 60 seconds

Data Quality 4 questions

Easy Coding round Fresher, Mid-level Practice question

8. After a load, how do you prove the target has no duplicate records for the same business key? Write the check.

What the interviewer is really testing:
Whether you check uniqueness on the business key that defines a row, not on a surrogate ID that is always unique.
Answer frame:

Pick the right key: the business key or grain columns, not the surrogate key the load generates.

The query: group by those columns and keep groups with more than one row.

Why it happens: reruns, a join that fans out, or overlapping extract windows.

Sample spoken answer:

"First I decide which columns should be unique. That's the business key, or for a fact table the grain, like order ID plus line number. Checking the surrogate key is pointless, because the load generates a new one for every row, so it's always unique even when the data is duplicated. Then it's a group by on those columns with HAVING COUNT(*) greater than one. Any row returned is a defect. A quick sanity check alongside it is comparing COUNT(*) with the count of distinct keys. When I find duplicates, the cause is usually one of three things: the job was rerun and inserted instead of upserting, a join to a lookup table matched more than one row, or two incremental windows overlapped. Knowing which one tells the developer where to look."

Code:
SELECT order_id, line_no, COUNT(*) AS copies
FROM fact_order_line
GROUP BY order_id, line_no
HAVING COUNT(*) > 1;
Red flag to avoid:

Checking uniqueness on the generated surrogate key and declaring there are no duplicates.

They may ask next:
  • In a Type 2 dimension the same customer ID appears several times. Is that a duplicate?
  • How would you find which join caused the fan-out?
Say it in 60 seconds
Easy Technical round Fresher Practice question

9. What null checks do you run on a load, and how do you test a column where the rule says missing values get a default?

What the interviewer is really testing:
Whether you test mandatory fields and default rules from both sides, including values that only look empty.
Answer frame:

Mandatory columns: count nulls in every column the mapping marks as required; the answer should be zero.

Default rules: feed source rows with nulls and confirm the target holds the default, not a null.

Look-alikes: empty strings, spaces and placeholders like 'N/A' that aren't null but mean missing.

Sample spoken answer:

"For each column the mapping says is mandatory, I count the nulls in the target, and that count should be zero. For columns with a default rule, say a missing country becomes 'UNKNOWN', I test it from both sides. I make sure the source actually has nulls in my test data, then confirm those rows land with the default and not with a null, and that rows with a real value keep it. Then I look at values that aren't null but act like it: empty strings, a string of spaces, or placeholders like 'N/A' or a dummy date. Different source systems send missing data in different ways, and the rule often forgets one of them. I also compare the null count per column between source and target. If the source had 20 null emails and the target has 200, a transformation is wiping values."

Red flag to avoid:

Only checking for NULL and overlooking blanks, spaces and placeholder values that mean the same thing.

They may ask next:
  • Should the job reject a row with a missing mandatory field, or load it with a default? Who decides?
  • What happens when a transformation concatenates a null with another string?
Say it in 60 seconds
Medium Coding round Fresher, Mid-level Practice question

10. How do you check that every row in a fact table points to a valid dimension row? Write the query.

What the interviewer is really testing:
Whether you test referential integrity yourself, since warehouses often don't enforce foreign keys, and whether you know about unknown members.
Answer frame:

Orphans: left join the fact to each dimension and keep fact rows with no match.

Unknown members: count rows mapped to the default 'unknown' key; a spike means lookups are failing.

Late arrivals: a fact can arrive before its dimension row, so check what the design says happens then.

Sample spoken answer:

"Many warehouses don't enforce foreign keys, for load speed, so I check them myself. I left join the fact table to each dimension on the key and keep rows where the dimension side is null. Those are orphans, and each one is a defect. But a clean result doesn't finish the job, because many designs avoid orphans on purpose. They map a failed lookup to a special 'unknown' row, often with a key like minus one. So I also count how many facts point to that unknown member. A handful might be normal. Thousands after a load means the lookup is broken, maybe a code changed case or picked up a trailing space. Last, I ask how late-arriving dimensions are handled, where a sale arrives before the product is set up, and I test that those facts get fixed once the product row arrives."

Code:
SELECT f.sale_id, f.product_key
FROM fact_sales f
LEFT JOIN dim_product d
  ON d.product_key = f.product_key
WHERE d.product_key IS NULL;
Red flag to avoid:

Assuming the database's constraints guarantee integrity without checking whether they're enforced at all.

They may ask next:
  • How would you test that the unknown member gets replaced once the real dimension row arrives?
  • Why might a warehouse team choose not to enforce foreign keys?
Say it in 60 seconds
Medium Technical round Mid-level Practice question

11. How do you test the way an ETL job handles bad records, the ones that fail validation?

What the interviewer is really testing:
Whether you test the unhappy path on purpose, and check that bad data is caught and explained rather than silently dropped or crashing the load.
Answer frame:

Seed bad data: nulls in required fields, invalid dates, unknown codes, text in number columns, oversized values.

Check the outcome: each bad row lands in the reject table or file with a clear reason; good rows still load.

Balance and alert: source equals loaded plus rejected, and thresholds fail the job or alert as designed.

Sample spoken answer:

"I build a small batch that mixes good rows with rows designed to fail each rule: a missing mandatory field, a date like the 31st of February, a status code that isn't in the lookup, text in a numeric column, a value longer than the target column. Then I run the job and check three things. Every bad row should be in the reject table or error file with a reason that says which rule it broke, so someone can fix it at the source. The good rows in the same batch should load normally, unless the design says one bad row stops everything. And the numbers should balance: source equals loaded plus rejected. I also test the threshold if there is one, like the job failing when too many rows are rejected, and that the alert actually reaches someone. Last, I check that reprocessed rejects don't turn into duplicates."

Red flag to avoid:

Testing only with clean data, or accepting that rejected rows just disappear.

They may ask next:
  • What would you say if the job simply skipped bad rows without logging them?
  • How should a corrected reject be reloaded without creating a duplicate?
Say it in 60 seconds

Transformation Rules 3 questions

Medium Coding round Mid-level Practice question

12. The mapping says each customer's segment comes from their total order amount. How do you test that rule? Show me the SQL.

What the interviewer is really testing:
Whether you test a transformation by recomputing it independently from the source, and think about boundaries and records the rule can miss.
Answer frame:

Recompute: write the rule yourself from the mapping, against the source, not by copying the developer's code.

Compare: join expected to loaded and return only rows that differ, handling nulls.

Edges: values exactly on each boundary, customers with no orders, and refunds or cancelled orders.

Sample spoken answer:

"I don't read the developer's code and agree with it. I write the rule again myself, straight from the mapping, against the source data. Here I sum each customer's orders, apply the thresholds in a CASE, and join that to the target. The query returns only rows where the loaded segment differs from mine, and I wrap the target side in COALESCE so a null segment shows up as a mismatch instead of being skipped. Then I think about edges. Does a total of exactly 1000 count as silver? The mapping has to say, and I make sure test data sits right on the line. Customers with no orders won't appear in my inner join, so I check separately that they get whatever the rule says. And I ask whether cancelled or refunded orders count, because that's a common gap."

Code:
SELECT t.customer_id, t.segment AS loaded, e.segment AS expected
FROM tgt_customer t
JOIN (
  SELECT customer_id,
         CASE WHEN SUM(amount) >= 10000 THEN 'GOLD'
              WHEN SUM(amount) >= 1000  THEN 'SILVER'
              ELSE 'BRONZE' END AS segment
  FROM src_orders
  GROUP BY customer_id
) e ON e.customer_id = t.customer_id
WHERE COALESCE(t.segment, '?') <> e.segment;
Red flag to avoid:

Testing a transformation by re-running the developer's own SQL, or ignoring boundary values.

They may ask next:
  • What if your query and the developer's code agree, but both read the mapping the same wrong way?
  • How would you test the same rule when it's applied incrementally, one day's orders at a time?
Say it in 60 seconds
Medium Technical round Fresher, Mid-level Practice question

13. A job builds a daily sales summary from order line items. How would you test the summary table?

What the interviewer is really testing:
Whether you can verify aggregated data by rebuilding it at the same grain and checking filters and day boundaries.
Answer frame:

Rebuild it: group the source line items by the summary's grain and compare measure by measure.

Totals: the overall total for a period must match the detail after the same filters.

Traps: day boundaries and time zones, cancelled or returned lines, and days with no sales.

Sample spoken answer:

"I rebuild the summary myself from the line items, grouping by exactly the same grain, say date and store, and compare each measure: quantity, gross amount, discount and number of orders. Then I check the overall total for a period equals the detail total, after the same filters. The filters are where most bugs are. Are cancelled lines excluded? Are returns subtracted, and on which day? Then I look at time. If orders are stored in one time zone and the report is by local business day, an order late at night can land on the wrong day. I also check a day with no sales: does the summary have a zero row or no row, and which one does the report expect? And if the summary is refreshed daily, I check that late-arriving orders update an older day correctly."

Red flag to avoid:

Checking only one grand total and missing that individual days or stores are wrong.

They may ask next:
  • How would you check a weekly count of distinct customers that someone built by adding up daily summaries?
  • What goes wrong when a report averages daily averages?
Say it in 60 seconds
Medium Technical round Fresher, Mid-level Practice question

14. What defects do you look for when data changes type or format on the way into the warehouse, like dates, decimals and codes?

What the interviewer is really testing:
Whether you know the quiet ways a conversion corrupts data without failing the job.
Answer frame:

Strings: truncation to the target length, trailing spaces, and encoding that mangles accented characters.

Numbers: lost precision, rounding versus truncation, and codes that lose leading zeros.

Dates: day and month swapped, time zones shifting the date, and invalid dates turned into defaults.

Sample spoken answer:

"Conversions are dangerous because they often don't fail, they just change the value. For text, I check the longest values in the source against the target column length, because some loads cut off the end without any error. I also check names with accents or non-Latin characters, since an encoding mismatch turns them into question marks. For numbers, I compare decimal places: a price with four decimals going into a two-decimal column gets rounded or cut, and the rule should say which. Codes like postal codes or account numbers can lose leading zeros if someone converts them to numbers. Dates are the worst. A source sending 03/04 might mean March or April depending on the format, so I test with a day above twelve. And a timestamp converted between time zones can move to a different date near midnight."

Red flag to avoid:

Assuming that if the job didn't error, every converted value is correct.

They may ask next:
  • How would you find truncated values after a load?
  • A source sends dates as text in two different formats. How would you test the parsing?
Say it in 60 seconds

SCD & Incremental 5 questions

Medium Technical round Fresher, Mid-level Practice question

15. Explain SCD Type 1, Type 2 and Type 3, and what you'd test for each one.

What the interviewer is really testing:
Whether you know how each type stores history and can turn that into specific checks.
Answer frame:

Type 1: overwrite the old value; test that the row updates in place and no history is kept.

Type 2: close the old row and insert a new version; test dates, current flags and new surrogate keys.

Type 3: keep the previous value in an extra column; test the shift from current to previous.

Sample spoken answer:

"Slowly changing dimensions are about what happens when an attribute changes, like a customer moving city. Type 1 simply overwrites. So I change the city in the source, run the load, and check there's still one row for that customer with the new city. Type 2 keeps full history. The old row gets an end date and its current flag turned off, and a new row is inserted with a new surrogate key, the new city, a start date and the flag on. I test there's exactly one current row per customer, that the dates chain without gaps or overlaps, and that old facts still point to the old version. Type 3 keeps limited history in a column, like previous city, so I test the old value moves into that column. For all of them, a row with no change shouldn't create anything."

Red flag to avoid:

Mixing up the types, or testing only the insert of a new version and not the closing of the old one.

They may ask next:
  • What should happen if a Type 2 attribute changes twice between two loads?
  • Which columns in a customer dimension would you expect to be Type 1 rather than Type 2?
Say it in 60 seconds
Hard Coding round Mid-level, Senior Practice question

16. Write queries to check a Type 2 customer dimension for bad history: several current rows for one customer, and gaps or overlaps between versions.

What the interviewer is really testing:
Whether you can turn Type 2 rules into precise SQL checks, using a window function to compare each version with the next.
Answer frame:

One current row: group current rows by business key; more than one is a defect, and so is none for an active key.

Chained dates: use LEAD to put each version's end date next to the next version's start date, and flag any older version left open.

Convention first: confirm whether a version ends on the next start date or the day before, then test that exact rule.

Sample spoken answer:

"The first check is simple: filter to current rows, group by customer ID, and flag any customer with more than one. I also check the other direction, active customers in the source with no current row at all. The second check is the history chain. I use LEAD over each customer's versions, ordered by start date, to put the next version's start next to this version's end. Before writing the condition I confirm the team's convention. In this query a version ends exactly where the next begins, so any row where they're not equal is either a gap, where the customer had no valid row for a while, or an overlap, where two versions were valid at once. The empty end date check catches an older version that was never closed, which is a classic defect. If the convention is that the end date is the day before the next start, I change the condition to match."

Code:
-- 1. More than one current row per customer
SELECT customer_id, COUNT(*) AS current_rows
FROM dim_customer
WHERE is_current = 'Y'
GROUP BY customer_id
HAVING COUNT(*) > 1;

-- 2. Gaps or overlaps between versions
SELECT customer_id, valid_from, valid_to, next_from
FROM (
  SELECT customer_id, valid_from, valid_to,
         LEAD(valid_from) OVER (
           PARTITION BY customer_id ORDER BY valid_from) AS next_from
  FROM dim_customer
) v
WHERE next_from IS NOT NULL
  AND (valid_to IS NULL OR next_from <> valid_to);
Red flag to avoid:

Checking only the current flag and never looking at whether the date ranges chain correctly.

They may ask next:
  • How would you check that facts loaded last year still point to the version that was current at the time?
  • What would you expect to see if the load ran twice with no source changes?
Say it in 60 seconds
Medium Technical round Fresher, Mid-level Practice question

17. What's the difference between a full load and an incremental load, and what test cases do you write for an incremental one?

What the interviewer is really testing:
Whether you understand how incremental loads find changes and where they typically miss or double-count records.
Answer frame:

Full vs incremental: a full load rebuilds everything; an incremental load picks up only rows changed since the last run, often by a timestamp or change log.

Core cases: new rows inserted, changed rows updated, unchanged rows untouched.

Edge cases: rows exactly at the watermark time, updates with no timestamp change, and the first ever run.

Sample spoken answer:

"A full load rebuilds the target from the whole source each time. It's simple but gets slow as data grows. An incremental load only picks up what changed since the last run, usually by comparing a last-updated timestamp with a saved watermark, or by reading a change log. For testing, I prepare three kinds of rows between two runs: brand new records, updated records, and records that didn't change. After the second run, new ones should be inserted, updated ones changed or versioned, and unchanged ones should be exactly as before, audit columns included. Then the edges. A record updated at exactly the watermark time is the classic miss or double count, depending on whether the filter uses greater-than or greater-than-or-equal. I check the watermark only moves when the run succeeds. And I check what happens when a source system updates a row without touching its timestamp."

Red flag to avoid:

Testing only new inserts and never checking updates, unchanged rows or the watermark boundary.

They may ask next:
  • Where would you store the watermark, and what happens to it if the job fails halfway?
  • How do you test the very first incremental run against an empty target?
Say it in 60 seconds
Hard Technical round Mid-level, Senior Practice question

18. The same daily batch gets run twice by mistake. How do you test that the load is safe to rerun?

What the interviewer is really testing:
Whether you test rerun and restart behaviour, which is where many production data incidents come from.
Answer frame:

Run twice: load a batch, snapshot counts, totals and row hashes, run the same batch again, and compare.

Expected result: no new rows, no new Type 2 versions, no changed totals; only audit columns move, if the design says so.

Restart case: stop the job halfway, rerun it, and check the end state equals one clean run.

Sample spoken answer:

"Rerun safety means running the same input twice leaves the target exactly as one run would. To test it, I load a batch, then take a snapshot: row counts per table, sums of the key measures, and a hash of every row for a sample of keys. Then I run the same batch again with the same parameters and compare. Nothing should grow. No duplicate fact rows, no new Type 2 versions for customers that didn't change, and no totals that doubled. When it fails, the usual cause is a plain insert instead of a merge, or a delete step that uses a different date range from the insert. The harder case is a failure in the middle, so I stop the job partway through, rerun it, and check the result matches a single clean run. That's the scenario that really happens at two in the morning."

Red flag to avoid:

Assuming the scheduler will never run a job twice, so rerun behaviour doesn't need a test.

They may ask next:
  • What design choices make a load safe to rerun?
  • How would you prove a rerun didn't create new Type 2 versions?
Say it in 60 seconds
Hard Technical round Mid-level, Senior Practice question

19. Records are sometimes deleted outright in the source system. How do you test that the warehouse notices, and what should happen to them?

What the interviewer is really testing:
Whether you know timestamp-based incremental loads can't see deletes, and can test the mechanism the team chose instead.
Answer frame:

The gap: a deleted row has no new timestamp, so a filter on last-changed time never picks it up.

Agree the rule: delete in the target, mark as deleted, or close the Type 2 version; the requirement must say which.

Test it: delete rows in the source, run the load, and check the target and the reports follow the rule.

Sample spoken answer:

"This one catches a lot of teams. If the incremental load picks up rows by their last-updated time, a deleted row just disappears from the source and nothing ever tells the warehouse. So first I find out how deletes are supposed to be detected: a change data capture feed that emits delete events, a regular key comparison between source and target, or soft deletes with a flag in the source. Then I confirm the rule for the target, because the business usually doesn't want history erased. Often the row stays but gets a deleted flag, or in a Type 2 dimension the current version is closed. For the test, I delete a few rows in the source, including one that was also updated earlier the same day, run the load, and check each one follows the rule. Then I check the reports drop them from the counts where they should."

Red flag to avoid:

Not realising that a timestamp-based incremental load never sees hard deletes.

They may ask next:
  • A row is deleted and then a new one is inserted with the same key. What should the warehouse show?
  • How would you find deletes that were already missed in the past?
Say it in 60 seconds

Warehouse Concepts 2 questions

Easy Technical round Fresher Practice question

20. What's the difference between a fact table and a dimension table, and how does each one change the way you test?

What the interviewer is really testing:
Whether you know the basic warehouse shapes well enough to pick the right checks for each.
Answer frame:

Facts: measurable events, like sales, at a stated grain, with keys pointing to dimensions.

Dimensions: descriptive context, like customer or product, often with history and a surrogate key.

Tests differ: facts get reconciled totals, grain uniqueness and key lookups; dimensions get attribute mapping, uniqueness and history checks.

Sample spoken answer:

"A fact table records events or measurements, like each sale with its quantity and amount, and holds keys that point to the dimensions. A dimension describes the who, what, where and when: customer, product, store, date. Facts are usually long and narrow and grow every day. Dimensions are wider and change more slowly. That changes how I test. For a fact table I reconcile measures against the source, like sums of amounts per day, check that the grain is unique, and check every key resolves to a dimension row. For a dimension I check each attribute against the mapping, that the business key is unique among current rows, that surrogate keys are unique, and that history is kept the way the design says, which is where the SCD tests come in. For the date dimension I also check there are no missing days."

Red flag to avoid:

Not knowing which table holds the numbers, or testing a dimension only by its row count.

They may ask next:
  • Where would a measure like discount amount go, and why?
  • What is a factless fact table, and how would you test one?
  • How does a snowflake schema change the joins you write in your tests compared with a star schema?
Say it in 60 seconds
Medium Technical round Mid-level Practice question

21. What does the grain of a fact table mean, and what goes wrong in reports when the grain isn't what everyone thinks?

What the interviewer is really testing:
Whether you understand grain as the definition of one row, and can connect it to double counting in real reports.
Answer frame:

Definition: the grain says exactly what one row represents, like one order line, or one account per day.

How to test: the grain columns must be unique together; check it with a group by.

Report risk: a join to a finer table, or summing a snapshot across days, inflates totals.

Sample spoken answer:

"The grain is the plain answer to 'what is one row in this table?' For example, one row per order line, or one row per account per day. It's the first thing I confirm before testing a fact, because every other check depends on it. To test it, I take the columns that define the grain and check they're unique together. If the design says one row per order line but I find order lines appearing twice, either the data is duplicated or the grain was never what the document claims. The damage shows up in reports. If someone joins an order-level table to line-level data, the order total repeats on every line, and summing it multiplies revenue. Or a daily balance snapshot gets summed across a month, and each balance is counted thirty times. So I check the grain and also how the reports aggregate it."

Red flag to avoid:

Describing grain vaguely as 'the level of detail' without being able to say what one row is.

They may ask next:
  • Which measures can you safely add up across days in a daily balance snapshot, and which can't you?
  • How would you spot a fan-out in a report query?
Say it in 60 seconds

Test Data & Tools 3 questions

Medium Technical round Fresher, Mid-level Practice question

22. How do you prepare test data for an ETL job so it covers the rules properly, and not just the happy path?

What the interviewer is really testing:
Whether you design test data deliberately from the mapping and rules, rather than relying on whatever production data happens to contain.
Answer frame:

From the rules: at least one row per rule branch, and rows sitting on each boundary.

Bad and odd data: nulls, blanks, duplicates, invalid dates, long strings, special characters, orphan keys.

Keep it usable: consistent keys across tables, written expected results, and scripts to reload it.

Sample spoken answer:

"I build it from the mapping, not from whatever's lying around. For every rule I want at least one row that takes each branch, and rows sitting right on the boundaries, like an amount exactly at a threshold or a time at midnight. Then I add the uncomfortable data: nulls and blank strings in required fields, duplicates on the business key, invalid dates, text at maximum length, names with accents and apostrophes, and fact rows pointing to dimension keys that don't exist. The keys have to hang together across tables, so records match where I want them to and break only where I mean them to. For each row I write down what the target should look like, so the test is a comparison, not a judgement call. And I script the setup so I can reload the same data for every regression run."

Red flag to avoid:

Relying only on a copy of production data and assuming it covers every rule.

They may ask next:
  • When is a masked copy of production data better than synthetic data?
  • How do you keep your test data in step when the mapping changes?
Say it in 60 seconds
Hard Technical round Mid-level, Senior Practice question

23. How do you test whether a load will still finish inside its batch window as data volumes grow?

What the interviewer is really testing:
Whether you can plan a realistic performance test for loads and find where the time goes, not just time the whole job.
Answer frame:

Realistic volume: test at production-like volume and at a projected future volume, not a few thousand rows.

Time each stage: measure extract, transform and load separately to find the bottleneck.

Usual causes: row-by-row processing, indexes during bulk inserts, unindexed lookups, and tiny commit batches.

Sample spoken answer:

"First I get the facts: how long the window is, what else runs in it, and how fast volume is growing. Then I test at today's production-like volume and at a projected volume, say what we expect in a year or two, because a load that fits today can quietly fail later. I measure each stage separately. If the whole job takes three hours, I want to know whether the time is in the extract, the transformations, or writing to the target. The usual culprits are processing rows one at a time instead of in sets, heavy indexes on the target during a bulk insert, lookups against huge tables without an index, and committing in tiny batches. For incremental loads, I also check that run time follows the number of changed rows, not the size of the whole table. If it grows with the table, something is scanning everything."

Red flag to avoid:

Timing one run on a tiny dataset and reporting that performance is fine.

They may ask next:
  • The load got twice as slow after a release, with the same data volume. Where do you look?
  • How would you test the load when the source system is also busy serving users?
Say it in 60 seconds
Easy Technical round Fresher, Mid-level Practice question

24. Which tools have you used for ETL testing, and how would you automate the checks you usually run by hand?

What the interviewer is really testing:
Whether you can talk about tools at a practical level and understand that repeatable, scheduled checks matter more than any one product.
Answer frame:

The core: SQL, a database client, and the ETL tool's own logs and run history.

Automation: store each check as a query with an expected result, and run them after every load from a script or test framework.

Reporting: failures raise an alert or stop the pipeline, and results are kept as evidence.

Sample spoken answer:

"The tool I use most is plain SQL in a database client, because nearly every check is a query. I've tested jobs built in graphical ETL tools and jobs written in code, and in both cases I also read the job logs and run history for row counts and rejects. For automation, I stop keeping queries in a notepad. Each check becomes a query that returns zero rows when things are fine, like the duplicate check or the orphan check, stored in version control with a name and the rule it tests. Then a small script or test framework runs them after every load and fails if any query returns rows. Some teams use a data validation library for this, and that's fine, the idea is the same. What matters is that the checks run every time, not only when a tester remembers."

Red flag to avoid:

Listing tool names without being able to explain what checks ran or how they were automated.

They may ask next:
  • Which of your checks would you run on every load, and which only before a release?
  • How do you stop an automated check failing every day because of a known, accepted difference?
Say it in 60 seconds

Real Work 3 questions

Medium Behavioral round Mid-level, Senior Practice question

25. Tell me about a data defect you found in an ETL load that had slipped past other checks. How did you find it?

What the interviewer is really testing:
Whether you have hands-on depth, a methodical way of tracing a data problem, and the habit of turning a find into a lasting check.
Answer frame:

Situation: the load, and why the existing checks looked green.

Trace: how you noticed, and how you narrowed it to the exact rule or step.

Result: the fix, and the check you added so it can't come back quietly.

Sample spoken answer:

"At my last company we loaded daily sales transactions into the warehouse. Row counts matched every day, the job was green, and it had passed testing. I was adding a check that compared amount totals per transaction type between source and target, and the sales total in the target was a bit higher than the source while refunds were lower. I pulled the keys that differed and found they all came from one new store system. It sent refunds with a new type code, and the transform had a CASE that treated any unknown code as a sale, so refunds were being added to revenue instead of taken off. The count was right because every row did arrive. We changed the rule so unknown codes go to the reject table instead of a default, reloaded the affected weeks, and I made the totals-per-type check part of the automated run."

Red flag to avoid:

A story with no detail about how the defect was traced, or one where the fix stops at the code change with no new check.

They may ask next:
  • Why hadn't the existing tests caught it?
  • How did you decide how far back to reload?
Say it in 60 seconds
Easy Behavioral round Fresher, Mid-level Practice question

26. Tell me about a time you had to test an ETL job with a mapping document that was incomplete or vague. What did you do?

What the interviewer is really testing:
Whether you push for clear expected results before testing, and handle ambiguity with the analyst and developer instead of guessing.
Answer frame:

Spot the gaps: list every rule where you can't write down the expected result.

Get answers: take specific questions, with source examples, to the analyst or business owner.

Record it: update the mapping so tests, code and reports follow the same agreed rule.

Sample spoken answer:

"On a project at my last company, I got a mapping for a customer dimension where several rules just said things like 'derive status' or 'clean the phone number'. I couldn't write an expected result for those, so I couldn't test them. Instead of guessing, I went through the whole document, listed every line like that, and for each one wrote a concrete question with an example from the source data, like 'this customer has an expired contract and an open ticket, is the status Active or Lapsed?' I took the list to the business analyst and the developer together. That helped, because the developer had already made assumptions for some of them and two were wrong. We updated the mapping with the agreed rules, and only then did I write the test cases. It cost two days up front but saved a round of defects later."

Red flag to avoid:

Saying you just tested whatever the developer built because the mapping wasn't clear.

They may ask next:
  • What would you do if the analyst couldn't answer before the release date?
  • How do you make sure the updated rules reach the developer's code?
Say it in 60 seconds
Medium Behavioral round Mid-level, Senior Practice question

27. Tell me about a time you built or improved an automated regression suite for a data warehouse. What did you automate first?

What the interviewer is really testing:
Whether you can prioritise automation by risk and value, and show a real outcome from it.
Answer frame:

Starting point: what regression looked like before and what it cost the team.

Choices: which checks you automated first, and why those.

Outcome: what changed, like defects caught earlier, faster releases, or fewer surprises in reports.

Sample spoken answer:

"When I joined my last team, regression for a release meant a tester running about two hundred saved queries by hand over three days, with results in spreadsheets. I didn't try to automate everything. I started with the checks that had caught real incidents in the past year, mostly reconciliation totals, duplicates on business keys and orphan keys on the big fact tables. I turned each one into a query that returns zero rows when things are fine, put them in version control, and wired them into a script that ran after the nightly load in the test environment and posted failures to the team channel. That took a couple of weeks. After that, regression for those tables took under an hour, and twice in the first month the nightly run caught a broken join before it reached testing."

Red flag to avoid:

Claiming everything was automated, with no sense of what was chosen first or why.

They may ask next:
  • How did you deal with checks that failed for known, accepted reasons?
  • What did you decide not to automate, and why?
Say it in 60 seconds

Judgement Calls 3 questions

Hard Situational round Mid-level, Senior Practice question

28. The load finished green, but the target is a few hundred rows short of the source, and the release is tonight. What do you do?

What the interviewer is really testing:
Whether you can investigate fast, separate a real defect from an expected difference, and give the release owner clear facts.
Answer frame:

Find the rows: compare keys to list exactly which records are missing, then look for a pattern.

Explain them: check rejects, filters, extract timing and recent changes before calling it a defect.

Report clearly: tell the release owner what's missing, the impact and the options, then let them decide with facts.

Sample spoken answer:

"First I stop comparing totals and find the actual missing rows by comparing keys, so I have a list instead of a number. Then I look for a pattern. Are they all from one source, one date, one status? I check the reject table first, then any filter rule in the mapping, then whether the source was still being written while the extract ran, which would make it an expected timing difference. If it's explained and matches the rules, I document it and we move on. If it isn't, I don't sit on it. I tell the release owner and the developer straight away: how many records, which ones, what the business impact is, like one region's sales being understated, and the options, fix now, release with a known issue and a reload, or delay. Whether it ships isn't my call alone, but nobody should decide without knowing."

Red flag to avoid:

Quietly passing it because the job was green, or blocking the release without finding out what the missing rows are.

They may ask next:
  • The developer says it's just timing. What would convince you?
  • What would make you recommend delaying the release outright?
Say it in 60 seconds
Medium Situational round Mid-level Practice question

29. You raise a defect for wrong values in the target, and the developer closes it saying the ETL is fine and the source data is bad. What do you do?

What the interviewer is really testing:
Whether you settle disagreements with evidence and route problems to the right owner instead of arguing or dropping them.
Answer frame:

Evidence: show the exact source rows, the mapping rule and the target rows side by side.

Find the owner: if the source is bad, its team fixes the data, but the ETL may still need to catch it.

Close properly: the defect is reassigned or turned into a new rule, not just closed.

Sample spoken answer:

"I don't argue in the ticket. I pull the evidence: a handful of the affected keys, the raw source values, the mapping rule, and what landed in the target, side by side. Sometimes that shows the developer is right. The source really is sending, say, negative quantities that shouldn't exist. Then the defect isn't closed, it's moved. The source team owns fixing the data, and we still ask whether the ETL should reject or flag those rows instead of loading them silently, which may be a new rule for the analyst to agree. Other times the evidence shows the source is fine and the transformation got it wrong, and then it's a normal defect again, with proof attached. Either way I keep it friendly. We both want correct numbers in the report, and a side-by-side usually ends the disagreement quickly."

Red flag to avoid:

Accepting the closure without evidence, or escalating a fight before showing anyone the rows.

They may ask next:
  • What if the source team says the data is valid for their system?
  • Should an ETL job ever fix bad source data by itself?
Say it in 60 seconds
Medium Situational round Mid-level, Senior Practice question

30. Your lead suggests copying last month's production data, including customer names and phone numbers, into the test environment. How do you respond?

What the interviewer is really testing:
Whether you take data privacy seriously in testing and can offer a workable alternative instead of just saying no.
Answer frame:

Raise the risk: personal data in a less protected environment can break privacy rules and company policy.

Offer options: a masked copy, synthetic data, or a small approved subset.

Keep it useful: masking must keep formats, keys and joins intact so tests still mean something.

Sample spoken answer:

"I understand why. Production data has variety that made-up data sometimes misses. But I'd raise the risk first. Test environments usually have wider access and weaker controls, and copying personal data there can break data protection rules, which differ by country, and almost certainly company policy. So I'd suggest a masked copy instead. Names, phone numbers, emails and addresses get replaced with realistic fake values, while keys stay consistent, so the same customer masks to the same value in every table and joins still work. Formats should stay valid too, so phone number rules can still be tested. Where we need real edge cases, I'd take the patterns from production, like the odd formats, and recreate them synthetically. And I'd check with whoever owns data protection first, so it's a decision on record."

Red flag to avoid:

Copying the data because it's convenient, or refusing without offering any way to get realistic data.

They may ask next:
  • How would you mask data so joins across tables still work?
  • What would you do if you found personal data already sitting in the test environment?
Say it in 60 seconds
Were you asked something else? Share it A person checks every question before it goes on the site. No name is shown.
For the call itself

The questions above are the prep. The call has ten more.

ClapAssist is an AI interview assistant for Mac and Windows. It listens to the interview on your computer and shows you what to say, in short lines you can read while you talk. Your resume and notes are never stored on our servers. It stays out of screen share on every plan; only you can see it.

Download ClapAssist with 10 free minutes
Mac and Windows · Stays out of screen share · No card