July 5th 2026 open source phpstan rule test helper phpstan
Custom PHPStan rules are a great way to enforce project-specific standards. Like all code, custom rules need tests, and PHPStan ships with a test harness for exactly that.
The PHPStan Rule Test Helper is a small open source library that builds on that harness and removes its two main maintenance niggles:
Install it with composer:
composer require --dev dave-liddament/phpstan-rule-test-helper
The library provides AbstractRuleTestCase, which extends PHPStan's RuleTestCase.
With PHPStan's standard test harness you assert that an error appears on a specific line of a fixture file. Add a line near the top of the fixture and every line number below it changes, so the test needs updating too.
With the helper, the expected errors live in the fixture itself.
A test extends AbstractRuleTestCase, specifies the rule being tested, and points at one or more fixture files:
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
class CallableFromRuleTest extends AbstractRuleTestCase
{
protected function getRule(): Rule
{
return new CallableFromRule($this->createReflectionProvider());
}
public function testAllowedCall(): void
{
$this->assertIssuesReported(__DIR__ . '/Fixtures/SomeCode.php');
}
}
In the fixture, every line containing an // ERROR comment is a line the rule should flag, and the text after // ERROR is the expected message:
class SomeCode
{
public function go(): void
{
$item = new Item("hello");
$item->updateName("world"); // ERROR Can not call method
}
}
Update the fixture and the expectations move with the code. There are no line numbers to fix up.
Most rules report the same message for every violation, so repeating it after each // ERROR comment is duplication.
Instead, define the message once in the test case:
use DaveLiddament\PhpstanRuleTestHelper\AbstractRuleTestCase;
class CallableFromRuleTest extends AbstractRuleTestCase
{
// `getRule` and `testAllowedCall` methods are as above and are omitted for brevity
protected function getErrorFormatter(): string
{
return "Can not call method";
}
}
Now the fixture only needs a bare // ERROR marker on each offending line:
class SomeCode
{
public function go(): void
{
$item = new Item("hello");
$item->updateName("world"); // ERROR
}
public function go2(): void
{
$item = new Item("hello");
$item->remove(); // ERROR
}
}
If the wording of the error message changes, there is one place to update it.
For messages that need context (e.g. naming the method or class involved), the helper also supports passing context after the // ERROR marker, with multiple values separated by |.
The PHPStan Rule Test Helper is available on GitHub and Packagist.