Write descriptive test names that clearly explain what is being tested
Follow the AAA pattern: Arrange, Act, Assert
Group related tests together in logical test suites
Keep tests independent - each test should be able to run in isolation
Write tests for both happy path and edge cases
Include tests for error conditions and invalid inputs
Test boundary conditions (empty strings, null values, maximum/minimum values)
All tests should have at least one assertion. Always use assertions instead of console logging to validate test results.
Aim for meaningful coverage, not just high percentage coverage
Keep tests simple and focused - test one thing at a time
Make tests deterministic - avoid randomness or time-dependent behavior
Use clear, descriptive assertions with helpful error messages
Avoid testing implementation details; focus on behavior and outcomes
Use minimal test data that clearly demonstrates the test case
Create reusable test fixtures and helper functions for common setup
Clean up resources after tests (database records, files, network connections)
Use test doubles (mocks, stubs, fakes) to isolate units under test
Keep tests fast - slow tests discourage frequent running
Make tests easy to read and maintain
Remove or update obsolete tests when code changes
Run tests frequently during development
Write tests that serve as documentation for expected behavior
Include comments for complex test logic or non-obvious test scenarios
Ensure test failures provide clear information about what went wrong