Reading a codebase; reading a diff
The genuinely new core skill. When an agent drafts the tests, your value is deciding whether the draft is right — which means reading unfamiliar code quickly and spotting what a diff quietly changed. Almost nobody teaches this; everybody now needs it.
A tester does not need to be able to write production code to test it well, but being unable to read it at all is a real handicap. Reading a codebase and a diff is a skill separate from writing software, closer to how an editor reads a manuscript than how an author writes one. It changes what bugs you find, because you start seeing the shape of a change instead of just the behavior it produces on screen. The same reading skill also underpins good API test design, whether you are checking HTTP and REST status codes or a schema field somewhere in an unfamiliar handler.
Reading a codebase without reading all of it
Nobody reads an unfamiliar codebase front to back. The useful approach starts at the edges: find the entry points (routes, API handlers, the main function) and trace inward only as far as the current question requires. If you are testing a checkout flow, you do not need to understand the whole billing system, just the path the checkout request actually takes through it.
Tests themselves are often the fastest way into unfamiliar code, since a well-named test describes intended behavior more directly than the implementation does. Reading the existing test suite before the source often orients a new tester faster than reading the source first, because tests show what the previous author considered worth protecting.
Reading a diff: what actually matters
A pull request diff is not just "lines added, lines removed." The signal worth looking for is the shape of the change relative to its stated purpose. A one-line bug fix that touches twelve files is either doing something more than it claims, or it is badly organized, and both are worth a question in review.
Three things worth checking on every diff before testing the change:
- Blast radius: does the diff touch shared code (a utility function, a base class) used by more than the feature it claims to fix. Shared-code changes need broader regression coverage than isolated ones.
- Removed code: deletions are easy to skim past, but a removed validation check or a deleted error handler is often the actual bug introduced by a "fix."
- Test changes: did the diff add tests, change existing ones, or ship with none. A diff that modifies an assertion to match new (possibly wrong) behavior, rather than adding a new test, is a signal worth flagging.
A worked example: the diff that looked smaller than it was
A backend engineer at a subscription software company submitted a pull request titled "fix: correct discount rounding," touching a single file with what looked like a two-line change to a rounding function. Consider what nearly happened next: the QA engineer reviewing it almost approved on the size alone, since small diffs are usually low risk.
Reading the diff more carefully surfaced the actual change: the rounding function was shared by three call sites, the discount calculator, the tax calculator, and an internal reporting job. The fix corrected rounding for discounts but, applied at the shared function level, silently changed the tax calculation's rounding behavior too, a case nobody had tested because the pull request's description only mentioned discounts.
The QA engineer traced the function's call sites using the codebase's own search tooling rather than trusting the diff's stated scope, found the shared usage, and asked the author to add a regression test for tax rounding specifically. That test caught a real off-by-one-cent discrepancy in the tax path before release, a bug the original diff's description gave no reason to suspect.
Reading code as risk assessment, not code review
QA reading a diff is doing something different from a developer reviewing it for correctness. The QA lens is: what is the smallest test that would catch this breaking, and what else does this change put at risk that the author might not have considered. That second question is why tracing shared-code usage, as in the example above, matters more for QA than for the author who already knows their own intent.
This same reading discipline extends into reviewing the pull request conversation itself, not just the code: commit messages, review comments, and CI status all carry information a diff alone does not.
FAQ
Questions people ask
Do I need to understand the programming language deeply to read a diff usefully?
Enough to follow control flow and function calls, but not enough to write idiomatic code in it. Reading comprehension and writing fluency are genuinely different skills here.
How do I find what else calls a shared function without reading the whole codebase?
Use your editor's or IDE's "find references" feature, or a code search tool, to list every call site before assuming a change's scope matches its description.
What is the fastest way to get oriented in a large, unfamiliar codebase?
Start from an entry point relevant to what you are testing, and read the existing test suite for that area before the implementation, since tests describe intent more directly.
Should I trust a pull request's description of what it changes?
Treat it as a starting hypothesis, not a fact. Verify it against the actual diff, especially for changes touching shared or widely used code.