Code Coverage Java Testing | Fresher Interview
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
Code coverage measures the percentage of your code that runs when the tests execute. There are a few types. Line coverage tracks which lines ran. Branch coverage tracks which if-else paths you took. Method coverage tracks which methods were called. A tool like JaCoCo generates a report showing this, usually green for covered and red for uncovered.
A good target depends on the project and the risk of the code. Critical payment or authorization paths need stronger evidence than trivial mapping code, regardless of the overall percentage. For trivial code like getters and auto-generated methods, I wouldn't chase coverage at all. The key point is that high coverage is necessary but not sufficient. You can hit a hundred percent with tests that don't actually verify anything — for example, a test that calls every method but never asserts on the result. The lines ran, so coverage goes up, but the test proves nothing. So I treat coverage as a floor, not a goal. If critical code sits at forty percent, that's a problem and I write more tests; but I don't pad the number with meaningless tests.
One mistake is assuming a hundred percent coverage means the tests are good — it doesn't; you have to look at what the tests actually check. Another is ignoring branch coverage. A method can have full line coverage but only fifty percent branch coverage if you never tested the else paths.
Code Coverage Java Testing | Fresher Interview
Direct Answer
Code coverage measures the percentage of code executed while tests run — common types are line, branch, and method coverage (JaCoCo is the standard Java tool). A useful target is chosen from the project risk and team quality gate, but coverage is necessary, not sufficient: you can hit 100% with tests that execute code yet assert nothing. Treat it as a floor that finds untested code, not a goal.
Code Example
class PaymentProcessor {
PaymentResult process(Payment p) {
if (p.amount() <= 0) return new PaymentResult(false, "Invalid amount"); // branch 1
if (p.cardNumber().length() != 16) return new PaymentResult(false, "Invalid card"); // branch 2
return new PaymentResult(true, "Success"); // branch 3
}
}
// Only the happy path: high line coverage, but ~33% BRANCH coverage
@Test void happyPath() {
var r = processor.process(new Payment(100.0, "1234567812345678"));
assertThat(r.success()).isTrue(); // branches 1 and 2 never tested
}
// Cover the rejected branches too -> full branch coverage
@Test void rejectsNegativeAmount() {
assertThat(processor.process(new Payment(-10.0, "1234567812345678")).success()).isFalse();
}
@Test void rejectsBadCardLength() {
assertThat(processor.process(new Payment(100.0, "123")).success()).isFalse();
}
Common Mistakes & Pitfalls
- Chasing 100%. It pushes people to write assert-nothing tests that inflate the number without catching bugs.
- Ignoring branch coverage. 100% line coverage can hide untested
elsepaths — branch coverage is the stricter signal. - Testing trivial code. Covering getters, setters, and generated
equals/hashCoderaises the number with zero value. - Not checking what's uncovered. 65% overall is fine — unless the missing 35% is payment validation.
Check your understanding
Answer these without looking back at the article.
- What is JaCoCo and how do you integrate it with Maven?
- What is mutation testing?
- Why is 100% code coverage not always the goal?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.