- Do I need to install sebastian/comparator directly in a Laravel app, or does PHPUnit already include it?
- In practically every Laravel codebase it is already installed transitively because phpunit/phpunit depends on it, so the assertEquals() calls in your tests are already using this package. Declaring it directly with composer require --dev sebastian/comparator only makes sense if you want to call its API explicitly or register your own comparators. Either way Composer usually resolves to the version PHPUnit already pinned.
- How do I install sebastian/comparator as a dev dependency in a Laravel project?
- Run composer require --dev sebastian/comparator. There is no service provider, config file, or facade to publish, because the library is framework-agnostic and lives in your test infrastructure layer. You then use SebastianBergmann\Comparator\Factory to resolve a comparator for a pair of values, or continue calling assertEquals() through PHPUnit or Pest as usual.
- Which PHP and Laravel versions does sebastian/comparator support?
- The project maintains parallel major branches that drop older PHP minors aggressively: the 8.x line requires PHP 8.4 or newer, 7.x requires PHP 8.3 or newer, and 6.x runs on PHP 8.2. That maps to Laravel 11 and 12 on PHP 8.3 or 8.4, and Laravel 10 or 11 on PHP 8.2. Feature availability, including the canonicalized array comparison fixes, is therefore gated by the PHP minor your application runs on.
- How do I register a custom comparator for Carbon or Illuminate Collection in Laravel?
- Create a class that extends SebastianBergmann\Comparator\Comparator, implement accepts() to match your types and assertEquals() to perform the comparison, then register an instance via Factory::getInstance()->register($comparator) inside your base TestCase. This is a supported API but an under-documented extension surface, so plan a small spike rather than assuming it works first try. Note that Comparator was briefly annotated as a private implementation detail and only un-marked in 7.1.2, so that surface has been unstable recently.
- How does sebastian/comparator report differences when a comparison fails?
- The comparator's assertEquals() either returns void on success or throws a SebastianBergmann\Comparator\ComparisonFailure exception. That exception carries the expected and actual values, their string representations, and a generated diff, which is what PHPUnit renders in your failure output. You can catch ComparisonFailure yourself if you want the diff outside of a test assertion.
- Can I use sebastian/comparator in production code to check whether two payloads are equal?
- That is the one anti-pattern to avoid. The API throws ComparisonFailure instead of returning a boolean, it builds diffs on failure which costs time and memory, and its version is dictated by PHPUnit's release train rather than your product's. Keep it in the test infrastructure layer and use strict comparison or dedicated value objects for equality checks in controllers, jobs, and services.
- Why does canonicalized array comparison in sebastian/comparator give false positives on older versions?
- The canonicalized array path accumulated four correctness fixes across 8.1.1, 8.1.2, 8.2.1, and the 7.1.x backports, covering mixed-type sort non-determinism, spl_object_id() sorting breaking arrays of equal objects, and a serious bug where string keys were destroyed during canonicalization. None of those fixes exist on the 6.x line used with PHP 8.2, so order-agnostic JSON or Eloquent assertions can silently pass. Either move to a supported PHP minor and package major, or avoid canonicalized comparison until you do.
- Does sebastian/comparator work with Pest and Laravel's HTTP JSON assertions?
- Yes. Pest's expect()->toEqual() and PHPUnit's assertEquals(), which Laravel's assertJson and assertExactJson style assertions build on, route through this library, so its comparator selection and diff output are already driving your results. If you need type-aware equality for Carbon, enums, Collections, DOMNode, BcMath\Number, Closure, or DateInterval, that behaviour comes from here. Understanding the package mainly helps when you need to debug a surprising pass or fail.
- What are the alternatives to sebastian/comparator for equality assertions in Laravel?
- Most teams do not replace it, because PHPUnit and Pest expose equality assertions that use this package underneath, so an alternative would just be a different wrapper around the same comparisons. Real alternatives are writing narrow domain-specific assertions for your own value objects, or using strict identity checks where type coercion is not wanted. For test assertions the practical question is which comparator major your PHP version pins, not which package to swap in.
- Is sebastian/comparator actively maintained and safe to rely on?
- It is maintained by Sebastian Bergmann as part of the PHPUnit ecosystem, with parallel major branches and a policy of dropping older PHP minors quickly. The reported Dependents count of zero is a GitHub-level artifact and does not reflect adoption, since PHPUnit pulls it into nearly every Laravel project. The real caution is that its edge-case semantics are subtle, with past issues around INF versus -INF, XML documents differing only by comments, and destroyed string keys, so treat it as a pinned and verified dependency rather than a just-works utility.