Treat tests like production code

A test suite is a software product maintained by your team. Give it clear boundaries, predictable setup, and meaningful failure messages.

Prefer user-facing locators

Use roles and accessible names when they describe stable user behavior. Test IDs are useful when a meaningful user-facing locator is not available. Avoid encoding an entire DOM hierarchy into a selector.

Keep fixtures focused

Create the minimum state each test needs. Independent tests are easier to rerun, parallelize, and diagnose. Shared accounts and mutable global setup can turn unrelated scenarios into a chain of failures.

Wait for evidence

Use assertions that wait for the expected state. A fixed timeout can be too short on a slow runner and wasteful on a fast one. Wait for a visible result or a specific response when that is part of the behavior under test.

Review the maintenance cost

When a test fails repeatedly without identifying a product bug, investigate it. Quarantining a test can be a temporary measure, but give it an owner and a repair date.