hotmeteor/spectator
Testing helpers for your OpenAPI spec
v3.0.4
1.8M downloads/mo
#1866 most downloaded on Packagist
hotmeteor/spectator
What this package is like to depend on
Last release today
23 Aug 2026
Release timing varies
gaps range from 2 weeks to 12 months
Rarely documented
notes for 8 of 68 stable releases
Nothing withdrawn
no release was ever pulled
6 years old
68 releases · first in 2020
8 releases in the last 12 months
see the full history below
Release timeline
68 releases · May 2020 to Aug 2026Releases
latest 60 of 68-
v3.0.423 Aug 2026Nothing published for this version
-
v3.0.323 Aug 2026Nothing published for this version
-
v3.0.201 May 2026 -
v3.0.128 Apr 2026 -
v3.0.028 Apr 2026Release notes
Open source →v3 is a significant release that raises the platform floor, adds a suite of developer-experience tools, and fixes several validation edge cases.
Breaking Changes
Minimum requirements
- PHP 8.3+ required (was 8.1+)
- Laravel 12+ required (was 10+)
New config key
A newerror_formatkey is required inconfig/spectator.php. If you published the config in v2, add:'error_format' => env('SPECTATOR_ERROR_FORMAT', 'text'),
No behaviour change unless you set
SPECTATOR_ERROR_FORMAT=json.Internal type changes (extenders only)
If you extend Spectator's validator classes, note that:'read'/'write'strings inAbstractValidatorare nowValidationMode::Read/ValidationMode::Writeenum casesFormat::TEXT_GREENstyle class constants are nowFormat::TextGreenstring-backed enum cases
These are internal details — if you only use the public facade and
TestResponseassertions, no action is required.See UPGRADE.md for the full list.
New Features
Artisan Commands
Four new artisan commands provide visibility into your spec and its relationship to your application.
spectator:validate— lint a spec file before tests run:php artisan spectator:validate --spec=Api.v1.yml php artisan spectator:validate --spec=Api.v1.yml --format=json
spectator:coverage— list every operation defined in the spec:php artisan spectator:coverage --spec=Api.v1.yml
spectator:routes— cross-reference spec operations against your registered Laravel routes:php artisan spectator:routes --spec=Api.v1.yml
Outputs matched, unimplemented, and undocumented routes at a glance.
spectator:stubs— generate skeleton test classes from a spec, ready to fill in:php artisan spectator:stubs --spec=Api.v1.yml --output=tests/Contract
Operations are grouped by tag (falling back to path segment), producing one test class per group with one
markTestIncompletemethod per operation.All commands support
--format=jsonfor machine-readable output.PHPUnit Coverage Extension
SpectatorExtensionis a PHPUnit 11 extension that tracks which spec operations are exercised across the full test run and prints a summary table when the suite finishes. Configure a minimum threshold to fail CI when coverage drops:<extensions> <bootstrap class="Spectator\Coverage\SpectatorExtension"> <parameter name="min_coverage" value="80"/> </bootstrap> </extensions>
JSON Error Format
Validation errors can now be emitted as structured JSON instead of ANSI-coloured text — useful for CI log parsers, LLM-driven workflows, and anything that processes test output programmatically:
SPECTATOR_ERROR_FORMAT=json
Or toggle per test:
Spectator::useJsonErrors(); Spectator::useTextErrors();
A failed assertion with JSON errors produces:
{ "errors": ["The data (null) must match the type: string"] }Fluent Path Prefix API
Spectator::withPathPrefix('v1');
As an alternative to setting
SPECTATOR_PATH_PREFIXin.env.AI & CI Integration
The combination of
spectator:validate --format=json,SPECTATOR_ERROR_FORMAT=json, andSpectatorExtensionmakes Spectator a natural fit for AI-driven development workflows — structured outputs at every stage mean errors and coverage gaps can be piped directly into LLM toolchains.
Bug Fixes
-
Nullable inside
additionalPropertiesnot migrated — OpenAPI 3.0nullable: trueon dictionary value schemas was silently skipped during the 3.0 to 3.1 nullable migration. Values likenullwere incorrectly rejected. (#215) -
Comma-separated values in header parameters —
explode: falsewithtype: arrayonin: headerparameters now correctly splits the comma-separated string into an array before validation, matching the existing behaviour for query parameters. (inspired by #213) -
TypeError with empty request body on
allOfschemas — sending an empty body against a requiredallOfrequest body no longer throws aTypeError. The error is now a clean "Request body required!" validation failure. (#216) -
Nullable properties inside
allOf—nullable: trueon properties nested withinallOfarms is correctly migrated to 3.1-styletype: [T, null]. (#212)
Internals
- PHP enums replace string and class constants throughout (
ValidationMode,Format,Source) - First-class callables,
readonlyproperties, andmatchexpressions used where appropriate - PHPStan level 6 enforced in CI with zero errors
- Test suite expanded from ~180 to 248 test cases
- GitHub Actions matrix covers PHP 8.3/8.4 x Laravel 12/13
- All dependency version constraints loosened on the upper bound so future Laravel versions work without a constraint update
Full Changelog
-
v2.3.028 Apr 2026 -
v2.2.128 Apr 2026Release notes
Open source →What's Changed
- Fix: objects without properties, and arrays without items by @philsturgeon in #219
New Contributors
- @philsturgeon made their first contribution in #219
Full Changelog: v2.2.0...v2.2.1
-
v2.2.027 Mar 2026Release notes
Open source → -
v2.1.204 Jun 2025Release notes
Open source →What's Changed
- Run tests on PHP 8.4 by @bastien-phi in #205
- Fix route matching where route declares regular expression constraints by @bastien-phi in #211
Full Changelog: v2.1.1...v2.1.2
-
2.1.102 Jun 2025Release notes
Open source →What's Changed
- cachedSpecs is initialized every time. by @hirotaka056 in #209
New Contributors
- @hirotaka056 made their first contribution in #209
Full Changelog: v2.1.0...v2.1.1
-
2.1.013 Mar 2025Nothing published for this version
-
v1.11.016 Jan 2024Nothing published for this version
-
v1.10.011 Aug 2023Nothing published for this version
-
v1.9.128 Jul 2023Nothing published for this version
-
v1.9.028 Jul 2023Nothing published for this version
-
v1.8.021 Feb 2023Nothing published for this version
-
v1.7.124 Oct 2022Nothing published for this version
-
v1.7.007 Sep 2022Nothing published for this version
-
v1.6.008 Aug 2022Nothing published for this version
-
v1.5.108 Aug 2022Nothing published for this version
-
v1.5.021 Feb 2022Nothing published for this version
-
v1.4.125 Jan 2022Nothing published for this version
-
v1.4.010 Dec 2021Nothing published for this version
-
v1.3.006 Oct 2021Nothing published for this version
-
v1.2.314 Sep 2021Nothing published for this version
-
v1.2.224 May 2021Nothing published for this version
-
v1.2.121 May 2021Nothing published for this version
-
v1.2.018 May 2021Nothing published for this version
-
v1.1.115 May 2021Nothing published for this version
-
v1.1.013 May 2021Nothing published for this version
-
v1.0.513 May 2021Nothing published for this version
-
v1.0.413 May 2021Nothing published for this version
-
v1.0.311 May 2021Nothing published for this version
-
v1.0.203 May 2021Nothing published for this version
-
v1.0.121 Apr 2021Nothing published for this version
-
v1.0.021 Apr 2021Nothing published for this version
-
v0.8.517 Feb 2021Nothing published for this version
-
v0.8.416 Feb 2021Nothing published for this version
-
v0.8.316 Feb 2021Nothing published for this version
-
v0.8.205 Feb 2021Nothing published for this version
-
v0.8.102 Feb 2021Nothing published for this version
-
v0.8.027 Jan 2021Nothing published for this version
-
v0.7.127 Jan 2021Nothing published for this version
-
v0.7.018 Dec 2020Nothing published for this version
-
v0.6.510 Dec 2020Nothing published for this version
-
v0.6.401 Dec 2020Nothing published for this version
-
v0.6.329 Nov 2020Nothing published for this version
-
v0.6.221 Nov 2020Nothing published for this version
-
v0.6.120 Nov 2020Nothing published for this version
-
v0.6.020 Nov 2020Nothing published for this version
-
v0.5.519 Nov 2020Nothing published for this version
-
v0.5.409 Nov 2020Nothing published for this version
-
v0.5.302 Nov 2020Nothing published for this version
-
v0.5.202 Nov 2020Nothing published for this version
-
v0.5.102 Nov 2020Nothing published for this version
-
v0.5.031 Oct 2020Nothing published for this version
-
v0.4.017 Oct 2020Nothing published for this version
-
v0.3.126 Jun 2020Nothing published for this version
-
v0.3.009 Jun 2020Nothing published for this version
-
v0.2.108 Jun 2020Nothing published for this version