QA & Testing Process

12 practices · Industry QA/testing practice guidance + shift-left testing principles

Testing practice that catches security problems as part of normal QA, rather than deferring them to a standalone pass that never quite happens.

Ticking these off for a specific project? The Project Security Checklist tracks all nine categories in one place. For why these patterns keep recurring, see Security Best Practices.

1. Unit/Regression Suite Runs on Every PR, Not Just Before Release

Description

Automated tests execute on every pull request and block the merge on failure — catching a broken fix the same day it's introduced, instead of during a pre-release scramble when it's expensive to trace back.

Example
GitHub Actions: on: pull_request
run: npm test -- --ci
required status check before merge is allowed

2. Test Coverage Is Tracked, Reviewed, and Trending in the Right Direction

Description

Coverage is measured automatically and watched over time — not just claimed. The goal isn't 100%; it's knowing which parts of the codebase have no safety net at all, especially auth and payment code.

Example
CI coverage report + fail build if coverage on
/src/auth/** or /src/payments/** drops below 80%

3. Test Plans Cover Negative & Abuse Cases, Not Just the Happy Path

Description

Every test plan explicitly lists what should be rejected — invalid input, wrong permissions, expired sessions, malformed payloads — not only the flow where everything goes right. A feature isn't "tested" if only the success path was exercised.

Example
Login test plan includes:
✓ correct password
✓ wrong password (5x → lockout)
✓ SQL-injection-shaped input
✓ expired/replayed session token

4. Security Checks Built Into Every Test Case, Not a Separate Pass

Description

Authorization ("can User B see User A's data"), input validation, and session handling are checked as part of normal functional testing — not deferred to an occasional standalone "security testing" sprint that never quite happens.

Example
Test case: "Delete invoice #123"
also asserts: as User B, DELETE /invoices/123 → 403
not just: as owner, DELETE → 200

5. Test Environments Mirror Production Configuration

Description

Staging runs the same framework versions, feature flags, and security headers as production — a bug that "only happens in prod" usually means staging quietly drifted from it and stopped being a reliable signal.

Example
Config diff check in CI:
compare staging vs prod — Node version, env var
keys (not values), security header set

6. Smoke Test Production Immediately After Every Deploy

Description

A short automated (or manual) checklist runs against the live site right after each deploy — login works, checkout completes, key pages load — so a broken release is caught in minutes, not from the first angry support ticket.

Example
Post-deploy smoke test (Playwright, 5 min):
login → view dashboard → add to cart → checkout
alerts #deploys channel on any failure

7. A Shared Bug Severity Standard, Not Tester's Judgment Call

Description

Critical/High/Medium/Low has a written definition (data loss vs. cosmetic glitch vs. workaround exists) that testers, developers, and PMs all use the same way — so "priority" doesn't depend on who filed the ticket.

Example
Critical: data loss, security bypass, or full outage
High: core flow broken, no workaround
Medium: workaround exists   Low: cosmetic

8. Cross-Browser & Cross-Device Testing Before Release

Description

Every release is verified on the browser/device matrix that actually matters to your users, not just the developer's machine — Safari and mobile-viewport bugs are routinely the ones that ship silently otherwise.

Example
BrowserStack matrix: Chrome/Safari/Firefox (latest 2),
iOS Safari + Android Chrome, at 375px and 1440px widths

9. Bug Reports Include Reproduction Steps, Environment, and Expected vs. Actual

Description

A usable bug report lets anyone reproduce the issue without a follow-up question — exact steps, environment (browser/OS/account type), and what should have happened versus what did.

Example
Steps: 1) Log in as free-tier user 2) Go to /export
Expected: upgrade prompt shown
Actual: 500 error (see attached stack trace)

10. Exploratory Testing Alongside Scripted Test Cases

Description

Scripted test cases catch what you thought to write down; a dedicated block of unscripted, exploratory testing before release catches what nobody thought to write down — the two are complementary, not redundant.

Example
Pre-release: 2hr exploratory session
charter: "try to break checkout with unusual input
and browser back/forward navigation"

11. Accessibility Checks Are a Standard Part of QA, Not an Afterthought

Description

Keyboard navigation, screen-reader labels, and color contrast are checked as part of normal QA sign-off, using an automated scanner plus a manual keyboard-only pass — not addressed only after a complaint or audit.

Example
axe-core in CI (automated) +
manual pass: Tab through the full checkout flow,
no mouse — verify every control is reachable

12. A Documented Definition of Done That Includes QA Sign-off

Description

"Done" means code merged, tests passing, and QA has verified the feature against its acceptance criteria — not "the developer thinks it works." Writing this down once prevents it being renegotiated under deadline pressure.

Example
Definition of Done checklist (PR template):
☐ Tests added/passing  ☐ QA verified against AC
☐ No new Critical/High bugs open on this feature

Last updated: September 2026 · Source: Offspring — Security Best Practices.pptx (Part 4) + Security Best Practices Checklist.xlsx