What Pest tests should you run before deploying CMS changes?
What Pest tests should you run before deploying CMS changes?
Short answer: before every CMS deploy, run a focused Pest subset that proves (1) public pages render crawlable content, (2) published() scopes hide future posts, (3) SEO endpoints (sitemap.xml, robots.txt) reflect real data, and (4) write APIs (MCP/Filament paths) cannot bypass auth. Skip the full suite only when you are fixing unrelated code with zero CMS touch.
On Aviwebsquad I treat these as merge gates—not vanity coverage numbers.
Why CMS regressions hurt more than feature bugs
A broken checkout annoys users. A broken publish scope leaks drafts. A broken sitemap deindexes your blog. A broken crawlable fallback triggers AdSense “low value content” even when articles are fine.
CMS tests should protect distribution, not just CRUD.
My minimum deploy set (7 tests)
1. Homepage crawlable fallback
Assert id="inertia-static-fallback" exists, includes <h1>, and meta description appears before Vite module scripts. Proves non-JS clients and reviewers see substance.
2. Blog post show + Article schema props
Hit a factory-published post. Assert 200, inertia component blog/Show, and articleJsonLd present. Optional: strip tags from crawlableHtml and assert word count > 300.
3. Future published_at hidden
Create status=published with published_at = now()->addWeek(). Blog index and sitemap must not list it.
4. Sitemap honesty
- Includes
/blog, published posts, pages, categories with posts - Excludes empty categories and future-scheduled posts
5. Category archive crawlable copy
Category with description renders in static fallback; CollectionPage JSON prop exists.
6. Contact form happy path
POST valid payload (with reCAPTCHA faked in tests). Assert mail queued and DB row created.
7. MCP upsert auth
Token without mcp:cms.write gets 403. Valid token creates/updates post and respects published_at.
Run them:
vendor/bin/sail artisan test --compact \
tests/Feature/Seo/CrawlablePagesTest.php \
tests/Feature/Cms/SeoEndpointsTest.php \
tests/Feature/Api/McpUpsertBlogPostTest.php
Adjust paths to your project; keep the categories stable.
Tests I add when touching specific areas
| Change | Extra tests |
|---|---|
| Search | query matches title + tag slug |
| Comments | moderation flag, honeypot field |
| Media upload | MIME allowlist, collection name |
| Menus | primary/footer locations render |
| Legal pages | policy slugs 200 + canonical |
Pest patterns that age well
Factories over fixtures. BlogPost::factory()->published() encodes the scope rules once.
Inertia assertions for JSON-LD when schema is client-rendered:
$response->assertInertia(fn (Assert $page) => $page
->has('faqJsonLd')
->where('faqJsonLd.@type', 'FAQPage'));
RefreshDatabase on feature tests touching posts—CMS state rots fast without it.
Avoid brittle HTML equality. Assert substrings and invariants, not full Blade dumps.
What I deliberately do not test every deploy
- Full Filament Livewire flows (run weekly or pre-release)
- Browser tests unless changing JS navigation
- Every admin widget permutation
Solo maintainers need a 10-minute gate, not a 40-minute suite.
CI recommendation
- name: CMS smoke tests
run: vendor/bin/sail artisan test --compact tests/Feature/Seo tests/Feature/Cms/SeoEndpointsTest.php
Fail the deploy if SEO/CMS smoke fails—even when “only” frontend changed. Inertia still depends on controller props.
FAQ
Is 100% coverage worth it for a blog CMS?
No. Cover invariants: visibility, SEO surfaces, auth on writes, and public 200s for golden paths.
Should MCP tests hit production?
Never in CI. Test against local/Sail with Sanctum tokens from php artisan mcp:token.
How do I test scheduled posts go live?
Travel time in Pest:
$this->travel(8)->days();
// assert post now visible
Do architecture tests help?
php artisan test --filter=arch can ban env() outside config and enforce controller namespaces—useful guardrails, not a deploy blocker.
Bottom line
Treat Pest as your CMS seatbelt: small, uncomfortable for two minutes, invaluable when you refactor publish logic at midnight. The list above is what I run before shipping Aviwebsquad content changes—copy the categories, plug in your paths, and keep publishing without fearing invisible SEO regressions.