PHPackages                             odinns/phpstan-pest-this - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. odinns/phpstan-pest-this

ActivePhpstan-extension[Testing &amp; Quality](/categories/testing)

odinns/phpstan-pest-this
========================

PHPStan extensions to infer Pest closure $this type from test file mappings.

v1.0.1(3mo ago)11.8k[3 issues](https://github.com/odinns/phpstan-pest-this/issues)[2 PRs](https://github.com/odinns/phpstan-pest-this/pulls)8MITPHPPHP ^8.3CI passing

Since Feb 13Pushed 3w agoCompare

[ Source](https://github.com/odinns/phpstan-pest-this)[ Packagist](https://packagist.org/packages/odinns/phpstan-pest-this)[ Docs](https://github.com/odinns/phpstan-pest-this)[ RSS](/packages/odinns-phpstan-pest-this/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (3)Dependencies (4)Versions (7)Used By (8)

phpstan-pest-this
=================

[](#phpstan-pest-this)

PHPStan extensions that infer Pest closure `$this` type from configurable test-path mappings.

Why
---

[](#why)

Pest binds test closures at runtime, while PHPStan analyzes code statically. Without extra help, closure `$this` is commonly inferred as `PHPUnit\Framework\TestCase`, which can produce false positives in Pest suites.

Installation
------------

[](#installation)

```
composer require --dev odinns/phpstan-pest-this
```

Quick setup
-----------

[](#quick-setup)

Add the extension to your PHPStan config:

```
includes:
    - vendor/odinns/phpstan-pest-this/extension.neon
```

The extension does not provide default test case mappings. Configure how file paths map to your Pest base test case classes:

```
parameters:
    pestClosureThisTypeMap:
        -
            pathContains: '/tests/'
            class: Tests\TestCase
```

This is the common Laravel/Pest setup where feature and unit tests share `Tests\TestCase`.

If your project uses separate base test cases, map the more specific paths explicitly:

```
parameters:
    pestClosureThisTypeMap:
        -
            pathContains: '/tests/Feature/'
            class: Tests\Feature\TestCase
        -
            pathContains: '/tests/Unit/'
            class: Tests\Unit\TestCase
```

`pathContains` is a substring match against the analyzed file path. The first matching mapping wins.

Supported Pest calls
--------------------

[](#supported-pest-calls)

- Function calls: `it(...)`, `test(...)`, `beforeEach(...)`, `afterEach(...)`
- Fluent hooks: `uses(...)->beforeEach(...)`, `uses(...)->afterEach(...)`

Optional: Generate a PHPStan proxy test case
--------------------------------------------

[](#optional-generate-a-phpstan-proxy-test-case)

If your base test case has protected assertion helpers, PHPStan may flag visibility errors from Pest closures. Use the included generator to create a static-analysis-only proxy class with public wrappers.

After installation:

```
vendor/bin/generate-pest-proxy.php \
  --source="Tests\\Feature\\TestCase" \
  --target="tests/PHPStan/PestFeatureTestCase.php" \
  --namespace="Tests\\PHPStan" \
  --class="PestFeatureTestCase"
```

While developing this package locally:

```
php tools/generate-pest-proxy.php \
  --source="Tests\\Feature\\TestCase" \
  --target="tests/PHPStan/PestFeatureTestCase.php" \
  --namespace="Tests\\PHPStan" \
  --class="PestFeatureTestCase"
```

Then map the relevant directory to the generated proxy:

```
parameters:
    pestClosureThisTypeMap:
        -
            pathContains: '/tests/Feature/'
            class: Tests\PHPStan\PestFeatureTestCase
```

This proxy only affects static analysis. It does not change Pest runtime behavior.

Limitations
-----------

[](#limitations)

- The extension resolves closure `$this` type only.
- It does not infer dynamic properties automatically; declare those on your test case/traits.
- Mapping is path-substring based, so very broad patterns can match unintentionally.

Development
-----------

[](#development)

```
composer install
composer check
```

Troubleshooting
---------------

[](#troubleshooting)

- No effect in analysis: confirm `extension.neon` is included in your PHPStan config.
- Wrong inferred class: ensure mapping order is specific to broad (first match wins).
- Generator not found: use `vendor/bin/generate-pest-proxy.php` after install or `php tools/generate-pest-proxy.php` in this repository.

Versioning
----------

[](#versioning)

This package follows SemVer from `1.0.0` onward. Composer versions come from Git tags, not a `version` field in `composer.json`.

Contributing
------------

[](#contributing)

Keep changes narrow. This package teaches PHPStan about Pest closure `$this`; it should not grow runtime Pest behavior or framework glue.

Run `composer check` before opening a PR.

Security
--------

[](#security)

Report security issues privately through GitHub Security Advisories:

Please do not open public issues for security reports.

Changelog
---------

[](#changelog)

See `CHANGELOG.md` for release notes.

License
-------

[](#license)

MIT

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance68

Regular maintenance activity

Popularity23

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~35 days

Total

3

Last Release

115d ago

Major Versions

v0.1.0 → v1.0.02026-04-25

PHP version history (2 changes)v0.1.0PHP ^8.2

v1.0.1PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/10bbe1cbea253f250b899d5704fbe59fc91ee40b14c017527409482187f365a1?d=identicon)[odinns](/maintainers/odinns)

---

Top Contributors

[![odinns](https://avatars.githubusercontent.com/u/10807424?v=4)](https://github.com/odinns "odinns (5 commits)")

---

Tags

testingpestPHPStanstatic analysis

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/odinns-phpstan-pest-this/health.svg)

```
[![Health](https://phpackages.com/badges/odinns-phpstan-pest-this/health.svg)](https://phpackages.com/packages/odinns-phpstan-pest-this)
```

###  Alternatives

[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.5k60.6M10.5k](/packages/larastan-larastan)[shipmonk/dead-code-detector

Dead code detector to find unused PHP code via PHPStan extension. Can automatically remove dead PHP code. Supports libraries like Symfony, Doctrine, PHPUnit etc. Detects dead cycles. Can detect dead code that is tested.

5014.2M111](/packages/shipmonk-dead-code-detector)[phpstan/phpstan-doctrine

Doctrine extensions for PHPStan

67475.0M1.6k](/packages/phpstan-phpstan-doctrine)[phpstan/phpstan-symfony

Symfony Framework extensions and rules for PHPStan

79378.2M2.5k](/packages/phpstan-phpstan-symfony)[spaze/phpstan-disallowed-calls

PHPStan rules to detect disallowed method &amp; function calls, constant, namespace, attribute, property &amp; superglobal usages, with powerful rules to re-allow a call or a usage in places where it should be allowed.

33923.4M632](/packages/spaze-phpstan-disallowed-calls)[staabm/phpstan-dba

2962.6M2](/packages/staabm-phpstan-dba)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
