Test behavior, not implementation: Prioritize verification of externally observable behaviors (return values/errors/side effects/external interactions), avoid binding internal details and increasing refactoring costs
Repeatable, stable, maintainable: Tests should produce consistent results on any machine at any time; failure information can quickly locate problems
Layered testing: Use unit tests to ensure correct logic and high coverage (fast, stable, isolated dependencies), use integration tests to ensure correct key links (real/near-real dependencies, reduce reliance on mock), use e2e tests to ensure core user paths are available (isolated environment, small and precise, strong observability)
Isolate external dependencies when mocking: For boundary dependencies such as DB/HTTP/time/random/file system, control the test environment through interfaces and dependency injection