I reviewed a pull request with forty new tests. Every one passed. Not one of them could fail.
They logged in, clicked around, filled forms, and ended. No checks. The author believed that if the steps completed without an error, the app worked. Those tests ran for months and caught nothing.
An assertion is the sentence where your test says what should be true. Without one, you have a script that visits a page. With one, you have a test.
Everything your test does splits into two kinds of line.
Actions change something: click, type, select, navigate.
Assertions check something: this text is on screen, this count is 3, this URL ends in /dashboard.
⚠️ Common confusion: students click the button and forget to check the result.
It feels finished, because on screen you can see it worked. But the test cannot see. If you do not check, nothing is checked, and the test passes on a completely broken app.
After every action, ask: what changed, and how would I prove it?
Now the harder half, which is where experienced testers still get it wrong. A weak assertion is worse than no assertion, because it looks like protection while providing none.
Here are the three weak ones you will write without noticing.
Checking that something exists. The element is on the page, so the check passes. But an error message element that renders permanently and empty also exists. Check the content, not the presence.
Checking something vague. "The cart badge is visible." It was visible before the click too. That assertion passes whether the number changed to 2, stayed at 0, or turned into nonsense. Check the exact value your user depends on.
Checking only the happy path. Your login test uses the correct password and sees the dashboard. Good. Would it fail if the app let everyone in with any password? No. It would pass, cheerfully, on a serious security bug. Test what the app should refuse.
Here is the test I apply to my own assertions, and it is worth making a habit now: name the bug this would catch. If you cannot name one, the assertion is decoration.
This is not a metaphor here. Every problem on this site is graded by breaking the app on purpose and re-running your test. If your assertion is weak, the broken app still passes, and we tell you so. That is the fastest way to learn the difference.
Remember this: the action makes the app do something, the assertion makes it a test.