What the ten minutes are for
This format is built to watch you orient, not to see you finish. An interviewer who hands you a repository you have never seen, one red test and a hint-only assistant is grading the order you do things in. Strong candidates spend the first minutes making the problem smaller. Weak ones start reading the codebase from the top, or ask the assistant to fix it, and are no closer at minute ten than at minute one.
A plan that works fits in a short table, and saying it aloud at the start is part of the answer.
| Minutes | What you do | What you have at the end |
|---|
| 0 to 2 | Run the failing test alone and read the full output | The exact expected and actual values |
| 2 to 4 | Read the test: its name, its setup, its assertion | The rule in one sentence |
| 4 to 7 | Trace the call path from the test to the computation | The two or three functions that matter |
| 7 to 10 | Use the failing case to test one hypothesis | A suspected line and a reason for it |
Reproduce before you read
Running the test first does three things. It proves the failure is real on your machine rather than a stale report. It tells you whether the environment works at all, which in an unfamiliar codebase is not guaranteed. And it gives you the most precise evidence you will get all session: an expected value and an actual one. Every later debugging step leans on those two numbers.
Suppose the test is called test_voucher_applies_before_loyalty_discount, and it fails with 80.00 where it expects 81.00. Before opening any production file, you already know the rule: a voucher comes off first, then the loyalty percentage applies to what remains.
Read the test as the rule, then trace the call path
The test is the best documentation in the repository, because it is executable and someone wrote it on purpose. Read the setup to learn which objects the rule touches, and the assertion to learn what correct means. Then follow the call from the test into the code, one hop at a time, until you reach the place the number is computed. In an unfamiliar codebase this is far cheaper than reading modules in directory order, because the test has already chosen the path for you.
def price(order: Order) -> Decimal:
total = order.subtotal
total = apply_loyalty(total, order.customer)
total = apply_voucher(total, order.voucher)
return round_money(total)
Now use the failing case. The gap is exactly 1.00, which is 10 percent of the 10.00 voucher. That is what you get when the percentage is applied to the amount before the voucher instead of after it: 100 × 0.9 − 10 is 80, while (100 − 10) × 0.9 is 81. The size of the error has pointed at the order of two lines. This is the core debugging move in the round: a wrong number is evidence, and its arithmetic often names the cause.
Check one more thing before touching code. Look at the history of the test and of price. If the test is new, the rule may be new and the code was never written for it. If price changed recently, this is a regression and the commit that swapped the lines will say why. Those lead to different conversations.
Using a hint-only assistant well
An assistant that will not write the patch is still useful for the slow parts of orientation in an unfamiliar codebase. Ask it questions whose answers you can check against the code in seconds.
"Which functions does price call, and in which files?"
"Where else in the repository is apply_loyalty called?"
"Is there a test that asserts loyalty applies before vouchers?"
Each answer is a pointer, so open the file it names and confirm the lines exist. The last question matters most, because a second test that encodes the opposite order means the rule is disputed, not merely broken. The broader case for treating model output as a hypothesis on old code is made in the AI on brownfield codebases guide.
Verifying the fix
Swap the two lines, run the failing test, and watch it pass. Then make it fail on purpose: put the lines back and confirm the test goes red, so you know it is testing the order and not something incidental. Run the full suite. If another test now fails, you have found the conflicting rule. Raise it with the interviewer instead of editing both tests until they agree.
Patching the symptom instead of finding the rule
The answer that loses marks is the fastest-looking one: read the assertion, change the code until the number matches, and declare success. Sometimes it means asking the assistant for a fix, which it refuses. Sometimes it means editing the test's expected value, which "fixes" the build and breaks the business. A candidate who changes the test has decided the test is wrong without any evidence.
What separates strong debugging here is that every step produces evidence for the next one. The run gives you the values, the test gives you the rule, the call path gives you the code, and the arithmetic gives you the line. A fix reached that way can be explained, and explaining it is what the interviewer writes down.
Reproduce, read the test as the rule, and let the size of the error point at the line. Ask the assistant where things are, never what to type.
© 2026 Preptima. Originally published at preptima.com (opens in a new tab).