Practical Coding Rounds/Testing Under Time Pressure

TDD Mechanics: Red-Green-Refactor and Ping-Pong TDD

The red-green-refactor loop as muscle memory, and its paired-interview variant — ping-pong TDD, where you and the interviewer alternate writing the failing test and the code that makes it pass.

!!!2/5Theory: 20m1 problems

Why fluency here has to be automatic, not derived live

Ping-pong TDD rounds and refactoring rounds both assume you can write a test in your framework of choice without hesitation — the round is scored on your design and refactoring judgment, and every second spent recalling "how do I set up a basic test in this language again?" is a second not spent on what's actually being evaluated. A candidate who blanks on test-file syntax under pressure reads as under-prepared regardless of how strong their algorithmic instincts are elsewhere. This subtopic assumes you already know a testing framework in at least one of Python, Java, or JavaScript, and focuses on the rhythm — the thing that's actually being scored — rather than any one framework's API.

The loop, precisely

Red — write a test for behavior that doesn't exist yet, and watch it fail for the right reason. "Fail for the right reason" matters: a test that fails because of a typo or a missing import isn't yet telling you anything about your implementation. Before moving on, confirm the failure message actually describes the missing behavior, not a syntax problem.

Green — write the smallest amount of code that makes it pass, and no more. This is the step candidates most often get wrong under pressure, in the direction of doing too much: implementing the next three cases you can already anticipate, when the discipline of TDD specifically asks you not to — only write code that a currently-failing test demands. This isn't pedantry; it keeps you from building speculative generality for cases that might not actually be required, and it keeps every step small enough to reason about completely.

Refactor — improve the code's structure with the test suite as your safety net, changing behavior not at all. This step only works because the tests from every prior cycle are still running and still green; if a refactor breaks a previously-passing test, that's the safety net doing its job, not a setback. Refactor at every opportunity where the code that just went green is uglier than it needs to be — waiting until "later" to clean up is how a live round quietly turns into unmanaged technical debt with 20 minutes left on the clock.

Ping-pong TDD: the two-person variant

Ping-pong TDD is the standard pair-interview adaptation of this loop: one person writes a failing test, the other writes the minimum code to make it pass — then they swap roles, and the second person writes the next failing test while the first implements it. A few things this format specifically rewards that solo TDD doesn't:

  • Writing tests small enough to hand off cleanly. A test that requires paragraphs of setup before your partner can even understand what's being asked slows the whole exchange down — the strongest ping-pong test is the smallest one that moves the design forward by exactly one increment.
  • Implementing exactly what the test asks, not what you assume comes next. Since you didn't write the test, resist the temptation to also solve the case you're guessing is coming — that guess is your partner's role to introduce with the next test, and jumping ahead undercuts the format's whole point (distributed, incremental design, not one person driving the whole thing).
  • Narrating the handoff explicitly. "Okay, that's green — your turn to write the next failing test" keeps the round moving and signals you understand whose turn it is, which matters more in this format than it sounds.

A concrete way to build this as muscle memory

The Diamond Kata is specifically designed to compare an incremental TDD approach against an all-at-once implementation for the same small algorithm (print a diamond shape from a given letter) — working through it while deliberately narrating each red-green-refactor step out loud, as if an interviewer were present, is a fast way to convert this from "something I understand" into "something I don't have to think about."

Reference implementations in:

One Red-Green-Refactor Cycle, Start to Finish

The smallest possible complete loop: a failing test for behavior that doesn't exist yet, the minimum code to pass it, then a refactor with the test as a safety net — repeat for the next case.

# RED: write the test for behavior that doesn't exist yet def test_applies_percentage_discount(): assert apply_discount(100, percent=10) == 90 # NameError: apply_discount undefined # GREEN: minimum code to pass -- no more def apply_discount(price, percent): return price - (price * percent / 100) # REFACTOR: now that it's green, clean up with the test as a safety net def apply_discount(price: float, percent: float) -> float: return price * (1 - percent / 100)

The refactor step is safe specifically because the test from the RED step still runs after it — rerunning it and seeing green again is what makes the refactor a refactor and not a guess.

Further Resources (Optional)

Practice Problems

Interview relevancy:!!!Critical — must-have!!Important — highly recommended!Good to have~Niche — rarely asked