Skip to main content

Guide · coding-prep

How to Test Your Code in an Interview

Trace through your solution with three examples — the original, an edge case, and an adversarial one — before saying you're done. Catching a bug yourself in the test pass is one of the strongest signals you can give; relying on the interviewer to catch it is one of the weakest.

By Alex Chen, Founder, InterviewChamp.AI · Last updated

How do you test your code in a coding interview?

Trace through three examples out loud before declaring you're done: the original example from the prompt, one edge case, and one adversarial case. Most "this code works" claims fall apart on the second or third trace — and finding the bug yourself, in the test pass, scores significantly higher than letting the interviewer find it five minutes later.

The three-example test pass

Lock this into a habit. Once your code compiles in your head, run these three traces:

Trace 1 — The original example. Walk through the prompt's example, line by line, with values. "Input is [2,7,11,15], target is 9. First iteration: i=0, num=2, complement=7. Hash map is empty, so we add 2 -> 0 and move on. Second iteration: i=1, num=7, complement=2. We find 2 in the map at index 0. Return [0, 1]." If your code matches the expected output, that's confirmation — not proof.

Trace 2 — An edge case. Pick the most boring possible input: empty list, single element, all duplicates, all the same value, or the smallest non-trivial case (n=2). "What does my code do on [5] with target 5?" If your loop never enters, do you return the right sentinel? If you reference arr[0] before checking length, you've found a bug — that's the win.

Trace 3 — An adversarial case. This is the one most candidates skip. Pick the input most likely to break your solution. For a hash-map approach, that's an input with duplicates that need both indices. For a two-pointer approach, it's an input where the pointers should cross. For a recursive approach, it's the input that hits the deepest recursion (often degenerate or sorted-descending). The adversarial case is where the bug almost always hides.

How to trace out loud without losing the thread

Tracing is itself a learned skill. The technique:

  • Write down the state. On the whiteboard or in a comment, sketch a small table: variable name → value, updated each iteration.
  • Speak the values, not the variable names. "i is now 1, and num is 7" — not "i increments and num updates."
  • Mark the decision points. "We hit the if-branch here because complement is in the map."
  • State the output when you reach the return. "Returns [0, 1] — matches expected."

This is slower than tracing silently in your head, by design. The point is to make the trace audible, so the interviewer can catch a misstep if you make one — and so you can catch one yourself. Per the Pragmatic Engineer's writing on technical-interview signal, candidates who systematically verbalize their trace catch their own bugs at a much higher rate than candidates who run the trace silently.

When the trace catches a bug

The script is already written for you:

"Good — the trace caught that I'm not handling the empty case. Let me add an early return on line 2 and re-trace."

Three things happen when you do this:

  1. You demonstrated test discipline — finding bugs is the whole point of tracing.
  2. You owned the bug without apologizing — clean recovery.
  3. You re-verified the fix with a fresh trace — completing the loop.

This is one of the highest-leverage moments in the interview. The candidates who self-catch a bug in the test pass routinely score higher than candidates whose first solution was correct but who skipped the test pass.

Common bugs the test pass catches

The bugs that show up most often — pattern-recognize them so your adversarial case can target them:

  • Off-by-one in loop bounds (range(len(arr)) vs range(len(arr) - 1)).
  • Equality at boundaries in binary search (== vs >=).
  • Empty / single-element edge cases — loops that never enter.
  • Mutation while iterating — silent corruption, not a crash.

When you trace, expect one of these. The adversarial case exists specifically to surface them.

What to do after all three traces pass

Don't declare victory unilaterally. The script:

"I've traced through the original, the empty/single-element case, and the duplicates case — all return correctly. Is there a specific edge case you'd like me to verify, or anything else you'd like me to think about?"

This hands the interviewer back the lead. Half the time they'll say "looks good, let's talk complexity." The other half they'll suggest an edge case you didn't think of — and now you get to demonstrate handling it under live pressure, which is more graded signal than the original solution.

Indeed Career Guide research on technical-interview rubrics explicitly highlights "systematic testing of own code" as a positive rubric marker — and "declares done without verification" as a common reason candidates get marked down on solutions that were actually correct. The discipline is: three traces, three different purposes, then hand the lead back.


About the author: Alex Chen is the founder of InterviewChamp.AI and writes about the modern tech interview from the inside — what changed, what works for new grads, and where the old playbook fails.

Frequently asked questions

Do I need to write actual test code in an interview?
Usually no — trace through your code with example inputs out loud. Writing real assert-style tests is fine if there's plenty of time left and the round explicitly invites it, but live traces of 2-3 examples are what's actually being graded most of the time.
What examples should I trace through?
Three: the original example from the prompt, one edge case (empty input, single element, or duplicates), and one adversarial case (the input most likely to break your solution). The adversarial case is the one most candidates skip and where bugs hide.
Is it okay to use the same example I used to develop the solution?
Yes for the first trace — but you must also add a fresh example. If you only re-run the example you used while writing, you're not really testing; you're confirming your memory of what you wrote. New examples catch bugs old ones don't.
What do I do if my trace reveals a bug?
Celebrate it briefly out loud, then fix it. 'Good — the trace caught that I miscounted the boundary. Let me fix line 12.' Finding your own bug in the test pass is graded much higher than a clean solution that the interviewer later discovers is broken.
When should I stop testing and call it done?
After you've traced three examples, all pass, and you've explicitly stated 'I've checked empty input, single element, and the adversarial case' — then ask the interviewer if there's anything else they want to see tested. Don't unilaterally declare you're done.