Start here. This is the direct spoken answer to practice first.
Why this question matters
Brittle tests slow improvement because they report internal movement as product failure. The answer still needs room for interactions that are genuine contracts.
I drive the unit through its public API and assert the returned value, state change, emitted event, or error that callers can observe. I avoid assertions about private methods, local variable choices, or the exact order of internal helper calls. That lets the implementation change while the protected behavior stays fixed.