Test a independant function or unit of code at a time. Don't test and entire class (or similar) in 1 go.
Only have 1 assertion per test.
Tests should be independant without needing other tests to run first.
Create utilities to help with effective testing, setups etc
Make use of setups/teardowns (beforeEach, afterEach, etc) to set up tests and their data.
Use a determined input with a known output. Avoid testing cases where the input or output is fuzzy.
File system access
Reliance on real-world values, gravity constant, time and date, timezones etc. Set explict values for these instead of Date.now() for example. assert(Date.now()).Equals('2022-01-01') will only succeed once.
Mock network requests and other data that could be dependant on outside factors.
When debugging, write a failing test for the bug. If the passes, it means the bug is something else, or not understood.
When refactoring, ensure that the tests fail when the method is removed, check coverage for the method. If it isn't covered, write tests for the current method before refactoring. Otherwise, your refactor will not be safe.