testing
Technical notes on web development, DevOps, and AI integration.
30 articles
- 08:17testing
Admin E2E: Testing Role and Bidang Guards Through the UI
Three Playwright specs for the admin area: login through the real UI, CRUD down to permanent delete with API verification, and role/bidang guards tested up to the server's 403.
TL;DR: We moved admin E2E tests beyond happy paths to guardrails, logging in via UI and reusing the localStorage token. It covers full CRUD in the Tiptap editor and trash flow, verifying permanent deletes via API not just UI. It also validates authorization, hiding user management from editors and blocking bidang users with a 403.
#playwright#e2e#testing - 07:27testing
When the Migration Table Lies in Bidang Integration Tests
Green suite, stale schema: schema_migrations only logs executed files, a leftover Docker volume quietly carries the old schema.
TL;DR: Tests stayed green after adding the bidang column because a stale MySQL volume kept the old schema while the migration version looked current. With no new files to run, the migrator did nothing and left the mismatch invisible. Now volumes are wiped before integration runs so migrations rebuild a fresh schema and six bidang scope scenarios are reliably verified.
#go#mysql#testing - 05:05backend
Bidang RBAC Enforcement: The Middleware Gate and IN Filters
Enforcing the bidang scope in Go: middleware at the gate, IN filters in repositories, and subtests that read like the security policy.
TL;DR: Middleware at the gate verifies the JWT and injects the bidang scope so handlers stay clean. Repositories then filter by allowed modules using sqlx In, while announcements handle NULL as global, and global routes require ALL access. Leaving the repository fail-open keeps public calls simple, and subtests ensure scoped admins only see their own data.
#go#mysql#security - 04:19testing
E2E Tests You Can Re-run by Module Name
Forgetting spec filenames whenever one page needs testing? A thin resolver plus an honest coverage ledger.
TL;DR: A 73-line bash script maps module names to Playwright specs so you can rerun one page instead of the whole suite. It checks folders, matches spec files, forwards flags like headed mode, and lists modules from describe blocks. A companion ledger tracks coverage per feature and requires new code to update its row, keeping gaps visible.
#testing#playwright#e2e - 04:18testing
Unit Testing Whose Contents Are Not Just Unit Tests
One script per test tier: vet, integration against real MySQL, a smoke gate, up to Playwright E2E.
TL;DR: Scattered manual tests were often skipped, so they were consolidated into four strict scripts for backend, frontend, E2E and smoke. Backend handles Docker and runs integration tests serially on real MySQL, while smoke validates deployment endpoints and E2E wraps Playwright with retries. README now defines what to run when, so a passing backend script signals the shared team contract.
#testing#bash#go - 03:24testing
The Category CRUD Was Done. The Tests Did Not Exist
Shipping nested categories with zero tests worked until the QA checklist asked for proof: the boot env is a contract, and constraint edges need a real MySQL.
TL;DR: Nested categories were live with no test coverage, and even the health check was broken since it missed required env vars. I patched the env setup and added three MySQL-backed integration tests for tricky deletes that mocks would hide. They run with the integration tag and -p 1 to avoid collisions on the shared test database.
#golang#testing#mysql - 02:23testing
Parity tests without a shared validator
Two validation gates stay separate, but a parametrized test table binds both to the same accept/reject contract and the same error precedence.
TL;DR: Two standalone modules rejected bad configs differently, and sharing validation code at runtime wasn’t allowed due to isolation rules. Instead of merging code, a parametrized pytest table now feeds hostile inputs to both, ensuring they agree on accept versus reject. It also enforces resolve-first ordering where path traversal errors beat file shape errors, keeping docs updated and modules isolated.
#python#testing#plane - 21:24tooling
Version-aware preflight without breaking v2
Preflight v3 without breaking the frozen v2 validator.
TL;DR: V2 preflight blocked v3 configs, so a new pagesync preflight now validates v3 decisions and Pages while leaving the frozen v2 engine alone. Duplicate validators stay aligned via a shared adversarial test table that requires matching accept/reject outcomes and surfaces traversal errors first. Page sync verifies what Plane stored via retrieve-after-write name and hash checks instead of trusting hidden markers.
#plane#python#testing - 17:04tooling
All Unit Tests Green, Yet the Converter Still Broke
Three pull-side bugs slipped past unit tests that were green on each side; only the round-trip property test caught the unsynchronized two-sided contract.
TL;DR: A round-trip property test over real docs failed despite green unit tests, showing the push and pull sides followed different contracts. Fixes addressed nested bold links via a wrap stack, a regex stash leak fixed by looping, and empty quote markers needing canonicalization. The lesson is unit tests only prove local specs, so you need cross-boundary property tests.
#plane#python#markdown