Sparround

Test code quality and conventions

The core principle: test code is production code. We review it just as seriously, because we will maintain it for years too. The only difference is the audience — the test code's "user" is a future teammate.

Naming rules:

  • The test name states the behaviour: test('rejects login with expired password') — not test('test2')
  • File names match the feature: checkout-coupon.spec.ts
  • POM methods express user intent: applyCoupon(code) — not clickBtn3()
  • Locator variables named by the element's role: submitButton, errorAlert
  • Boolean helpers phrased as questions: isCartEmpty()

Structure rules: one test — one behaviour; the AAA split visible via blank lines; no if/for inside a test (conditional logic makes it non-deterministic — use parameterisation); never swallow failures with try/catch.

Automated enforcement beats human enforcement — keep conventions in the linter, not in a document. The TypeScript + ESLint (typed linting) + eslint-plugin-playwright + Prettier set ends team arguments: formatting is checked in CI, style debates leave code review, and review focuses on logic only.

The single most critical rule is no-floating-promises. The Playwright API is fully async; a line with a forgotten await silently doesn't execute and the test stays green — a false positive. This is the most dangerous class of bug in automation, because it produces no signal at all.

RuleWhat it prevents
@typescript-eslint/no-floating-promisesA missing await silently skipping the line — a falsely green test
playwright/no-wait-for-timeoutFixed sleeps — slowness and flakiness
playwright/no-focused-testA forgotten test.only — the suite going "green" on 1 test
playwright/expect-expectAn assertion-less "test" — a check that can never fail
playwright/no-conditional-in-testNon-deterministic, hard-to-explain tests built on if/else

A very strong interview answer to "what's the most dangerous test bug?"a forgotten `await`. The test is green but verifies nothing. Say you close it with the no-floating-promises lint rule — that shows "I solve problems once" thinking, a middle+ signal.

📚 Sources and documentation