Start with a result you can reproduce
Suppose a program turns the text “cat, dog” into a total number of letters. You expect 6, but it returns 7. Before examining the code, write down the exact input, the expected result, and the actual result. Run the same input again to confirm that the problem is repeatable. Without a clear starting point, it is easy to chase a different problem each time you test.
Next, trace the path that produces the result. In this example, the program might split the text at the comma, remove surrounding spaces, add the lengths of the entries, and turn the total into display text. You do not yet need to know which step is broken. You only need a rough sequence with a known input at one end and a wrong output at the other.
Inspect a checkpoint near the middle
Instead of reading every function from the top, inspect the value after the second of those four steps. If the entries have already been split and trimmed, you expect ["cat", "dog"]. If the value is correct there, the bug is likely in the later steps: adding lengths or formatting the result. If the value is wrong there, focus on the earlier steps: splitting or trimming. One check has ruled out roughly half the path.
You can use a breakpoint in a debugger, a temporary console.log, or a small test to inspect that value. Place the check at the boundary between steps, and record both what you expected and what you observed. A log that only says “got here” confirms that code ran, but it does not tell you whether its data is correct.
Repeat until you find the first wrong value
Assume the midpoint value is ["cat", " dog"]. The space before “dog” explains the extra character, so the problem is in the first half of the process. Now inspect the value immediately after splitting. If it is ["cat", " dog"], splitting has done what a comma split normally does: it preserved the space from the input. The trim step should remove that space but did not. You have narrowed the investigation to one function without needing to study the total-length or formatting code.
This approach resembles binary search, but you are searching through a path of transformations rather than a sorted list. On a long path, choose a checkpoint near the middle of the remaining suspect steps each time. On a short path, simply check the boundary that will answer the most useful question. The aim is to locate where correct data first becomes incorrect, not to divide the code into perfectly equal pieces.
Try the method in a JavaScript console
For a small exercise, you need a browser with a JavaScript console that supports ECMAScript 2015 or newer; no packages are required. Enter these definitions as one line: const splitEntries = text => text.split(","); const trimEntries = entries => entries.map(entry => entry); const totalLengths = entries => entries.reduce((sum, entry) => sum + entry.length, 0); const formatResult = total => String(total); The trimEntries function intentionally returns each entry unchanged, so this example contains a bug.
Now enter formatResult(totalLengths(trimEntries(splitEntries("cat, dog")))). It returns "7". Check the midpoint with trimEntries(splitEntries("cat, dog")); the second entry still begins with a space. Then check splitEntries("cat, dog"); its output shows that the space was present before trimming. The fix belongs in trimEntries: change its mapping expression to entries.map(entry => entry.trim()). Running the original input again should then return "6". Checking the final result after a fix matters: identifying a suspicious line is not the same as verifying the repair.
Use checkpoints without changing the bug
A useful checkpoint observes the program under the same conditions that produce the failure. Avoid replacing real input with a simpler value halfway through the investigation; doing so might hide the cause. If a function changes its input, inspecting that input later may also give a misleading picture of what it contained earlier. Pause at the boundary or record a snapshot of the relevant value when it passes through.
Not every bug follows one straight sequence. Event handlers, asynchronous work, and shared state can create several possible paths. First determine which path ran and reproduce the failure consistently; then apply the same halfway check within that path. Once you find the first wrong value, inspect the operation that produced it and add a focused test for the input that exposed the bug. That test gives you a quick way to check that the same mistake does not return.



