Assertions That Actually Tell You Something
By the end of this lesson, you'll be able to:
- Use System.assertEquals, assertNotEquals, and assert with clear failure messages
- Write an assertion specific enough to catch the actual bug it's meant to catch
- Recognize a weak assertion that would pass even with broken code
Prerequisites: "Test.startTest and Test.stopTest"
The core assertion methods
System.assertEquals(17.00, result, 'Expected the total to be 17.00');
System.assertNotEquals(null, savedRecord.Id, 'Expected the record to have been saved with an Id');
System.assert(list.size() > 0, 'Expected the list to contain at least one item');
System.assertEquals(17.00, result, 'Expected the total to be 17.00');— the message is the final argument.System.assertNotEquals(null, savedRecord.Id, 'Expected the record to have been saved with an Id');— same shape.System.assert(list.size() > 0, 'Expected the list to contain at least one item');— same shape again.
All three accept an optional message as their final argument — always worth including, since it's exactly what shows up in the test failure output, saving whoever's debugging a failed test from having to reverse-engineer what the assertion was even checking.
A weak assertion that hides real bugs
// WEAK: passes even if the method returns completely wrong data
System.assertNotEquals(null, result);
// STRONG: actually verifies the specific expected value
System.assertEquals('12 + 5 = 17.00', result);
// WEAK: passes even if the method returns completely wrong data— the label for the weak version.System.assertNotEquals(null, result);— only confirms something was returned — it would pass even ifcalculateAndFormat(12, 5, '+')returned'wrong answer'or'42'.- (blank line)
// STRONG: actually verifies the specific expected value— the label for the strong version.System.assertEquals('12 + 5 = 17.00', result);— this is exactly the kind of assertion that lets a real bug slip through a "passing" test suite, satisfying the coverage requirement (Lesson 1) while verifying almost nothing — the strong version actually checks it.
A concrete example: catching an off-by-one bug
@isTest
static void discountAppliesCorrectPercentage() {
Decimal result = DiscountCalculator.apply(200, 10); // 10% off 200
// WEAK — would still pass even with a subtle off-by-one bug
System.assert(result < 200);
// STRONG — catches the exact expected value, off-by-one bugs included
System.assertEquals(180, result);
}
@isTest— marks the test method.static void discountAppliesCorrectPercentage() {— the test.Decimal result = DiscountCalculator.apply(200, 10);— 10% off 200, so 180 is expected.- (blank line)
// WEAK — would still pass even with a subtle off-by-one bug— the label.System.assert(result < 200);— ifDiscountCalculator.applyhad a bug computing182instead of180, this would still pass.- (blank line)
// STRONG — catches the exact expected value, off-by-one bugs included— the label.System.assertEquals(180, result);— only the strong, specific assertion actually catches the discrepancy.}— closes the test method.
This is the single most important habit this lesson teaches: assert the exact expected value whenever one is knowable, not just a loose approximation of correctness.
Exercise
This assertion is too weak to catch a real bug. Rewrite it to check the exact expected total.
Show hint
Calculate the exact expected value and use assertEquals.
Assertions That Actually Tell You Something Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
A test with a vague or overly permissive assertion can pass even when the code is genuinely broken — this lesson focuses specifically on writing assertions that would actually fail if the bug they're meant to catch existed.