Download the PHP package helgesverre/pest-to-phpunit without Composer

On this page you can find all versions of the php package helgesverre/pest-to-phpunit. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package pest-to-phpunit

Pest to PHPUnit — Rector Extension

[!WARNING] This project is experimental. It handles many common Pest patterns, but edge cases may produce incorrect output. Always review the generated code before committing.

Latest Version on Packagist Total Downloads PHP Version

A Rector extension that automatically converts Pest test files into PHPUnit test classes.

Handles test() / it() blocks, hooks, datasets, expect() assertion chains, modifiers, and more — getting you most of the way there automatically while leaving clear TODO markers for anything that needs manual review.

Installation

Usage

1. Add the set to your rector.php

Namespace inference (recommended)

Pest test files typically have no namespace declaration. If your project uses PSR-4 autoloading for tests (e.g. "Tests\\": "tests/" in composer.json), enable namespace inference to automatically add the correct namespace to generated classes:

This reads your composer.json autoload-dev and autoload PSR-4 mappings to derive the namespace from the file path (e.g. tests/Feature/ExampleTest.phpnamespace Tests\Feature;).

2. Run Rector

3. Review TODO comments

Some Pest features cannot be auto-converted and will be marked with // TODO(Pest): comments. After running Rector, search for these to find anything that needs manual attention:

Examples

Basic test() / it()

Before:

After:

describe() blocks

Hooks → setUp / tearDown

uses() → extends + traits

Modifiers: skip(), todo(), throws(), group()

expect()->toThrow()

Pest Faker Plugin

The use function Pest\Faker\fake; import is automatically removed. $this->faker via the WithFaker trait works naturally through trait conversion (see uses() above).

Datasets → #[DataProvider]

Feature Support

Core Constructs

Pest Feature Status PHPUnit Output
test() / it() public function test_*(): void
describe() (nested, 4+ levels deep) Method name prefixing
beforeEach / afterEach setUp() / tearDown()
beforeAll / afterAll setUpBeforeClass() / tearDownAfterClass()
uses(TestCase::class) extends TestCase
uses(Trait::class) use Trait;
covers(Foo::class) #[CoversClass(Foo::class)]
coversNothing() #[CoversNothing]
dataset('name', [...]) Static data provider method
dataset('name', fn() => ...) Generator-based provider
Describe-scoped beforeEach/afterEach Inlined into test methods (try/finally for afterEach)
Non-Pest code preserved Kept alongside generated class

Test Modifiers

Modifier Status PHPUnit Output
->skip('reason') $this->markTestSkipped(...)
->skip($condition, 'reason') Conditional if + markTestSkipped
->todo() $this->markTestIncomplete('TODO')
->group('name') #[Group('name')]
->depends('test') #[Depends('test_*')]
->covers(Foo::class) #[CoversClass(Foo::class)]
->with('dataset') #[DataProvider('dataset')]
->with([...]) Inline provider method + #[DataProvider]
Multiple ->with() (cross-join) Composed cross-join provider method
->throws(Exception::class) expectException + expectExceptionMessage
->after(fn() => ...) Test body wrapped in try/finally
->repeat(N) for loop wrapping test body
->only() #[Group('only')]

expect() Assertions

Type Assertions

Pest Assertion Status PHPUnit Equivalent
toBeString / toBeInt / toBeFloat / toBeArray assertIsString / assertIsInt / assertIsFloat / assertIsArray
toBeBool / toBeCallable / toBeIterable assertIsBool / assertIsCallable / assertIsIterable
toBeNumeric / toBeObject / toBeResource / toBeScalar assertIsNumeric / assertIsObject / assertIsResource / assertIsScalar
toBeInstanceOf assertInstanceOf

Value Assertions

Pest Assertion Status PHPUnit Equivalent
toBe assertSame
toEqual assertEquals
toBeTrue / toBeFalse assertTrue / assertFalse
toBeTruthy / toBeFalsy assertNotEmpty / assertEmpty
toBeNull assertNull
toBeEmpty assertEmpty
toBeJson assertJson
toBeNan / toBeFinite / toBeInfinite assertNan / assertIsFinite / assertIsInfinite

Comparison Assertions

Pest Assertion Status PHPUnit Equivalent
toBeGreaterThan / toBeLessThan assertGreaterThan / assertLessThan
toBeGreaterThanOrEqual / toBeLessThanOrEqual assertGreaterThanOrEqual / assertLessThanOrEqual
toBeBetween($min, $max) assertGreaterThanOrEqual + assertLessThanOrEqual
toEqualWithDelta assertEqualsWithDelta
toEqualCanonicalizing assertEqualsCanonicalizing

String Assertions

Pest Assertion Status PHPUnit Equivalent
toStartWith / toEndWith assertStringStartsWith / assertStringEndsWith
toMatch assertMatchesRegularExpression
toContain (string subject) assertStringContainsString
toContain (array subject) assertContains
toContain($a, $b, $c) (multi-arg) Multiple assertContains calls

Array / Collection Assertions

Pest Assertion Status PHPUnit Equivalent
toHaveCount assertCount
toHaveLength assertSame($n, is_string($x) ? strlen($x) : count($x))
toHaveKey assertArrayHasKey
toHaveKeys(['a', 'b']) Multiple assertArrayHasKey calls
toContainEqual assertContainsEquals
toContainOnlyInstancesOf assertContainsOnlyInstancesOf
toHaveSameSize assertSameSize
toBeList assertIsList
toBeIn([$a, $b]) assertContains($subject, $haystack)
toMatchArray / toMatchObject assertEquals

Object Assertions

Pest Assertion Status PHPUnit Equivalent
toHaveProperty('name') assertObjectHasProperty
toHaveProperties(['a', 'b']) Multiple assertObjectHasProperty calls
toHaveProperties(['name' => 'John']) assertSame per key-value pair
toHaveMethod('foo') assertTrue(method_exists(...))
toMatchConstraint($c) assertThat($subject, $constraint)

File / Directory Assertions

Pest Assertion Status PHPUnit Equivalent
toBeFile / toBeDirectory assertFileExists / assertDirectoryExists
toBeReadableFile / toBeWritableFile assertFileIsReadable / assertFileIsWritable
toBeReadableDirectory / toBeWritableDirectory assertDirectoryIsReadable / assertDirectoryIsWritable

String Format Assertions (via regex)

Pest Assertion Status PHPUnit Equivalent
toBeUppercase / toBeLowercase assertSame(strtoupper($x), $x) / assertSame(strtolower($x), $x)
toBeAlpha / toBeAlphaNumeric / toBeDigits assertMatchesRegularExpression
toBeSnakeCase / toBeKebabCase / toBeCamelCase / toBeStudlyCase assertMatchesRegularExpression
toBeUuid / toBeUrl assertMatchesRegularExpression

Array Key Format Assertions

Pest Assertion Status PHPUnit Equivalent
toHaveSnakeCaseKeys / toHaveKebabCaseKeys foreach (array_keys(...)) + regex assert
toHaveCamelCaseKeys / toHaveStudlyCaseKeys foreach (array_keys(...)) + regex assert

Exception Assertions

Pest Assertion Status PHPUnit Equivalent
toThrow(Exception::class) expectException + invoke callable
toThrow(Exception::class, 'msg') expectException + expectExceptionMessage
toThrow(new Exception('msg')) expectException + expectExceptionMessage
toThrow('message') expectExceptionMessage
not->toThrow() try/catch with $this->fail() on exception

Laravel-Specific Assertions

Pest Assertion Status PHPUnit Equivalent
toBeCollection assertInstanceOf(Collection::class)
toBeModel assertInstanceOf(Model::class)
toBeEloquentCollection assertInstanceOf(EloquentCollection::class)

Chain Modifiers

Modifier Status Behavior
->not->* Negated equivalents (assertNotSame, assertNotNull, etc.)
->and($subject) Split into multiple assertion groups
->each->* (no closure) foreach loop with assertion per item
->tap(fn() => ...) Closure body inlined
->pipe(fn($v) => ...) Subject transformed: (fn($v) => ...)($subject)
Property access (e.g. ->name) $subject->name
Method access (e.g. ->count()) $subject->count()

Pest Plugins

Plugin Status Behavior
pest-plugin-fakerfake() Converted to \Faker\Factory::create(), locale arg preserved
pest-plugin-fakerfake('pt_PT') Converted to \Faker\Factory::create('pt_PT')
pest-plugin-fakerWithFaker trait Works via uses() trait conversion, $this->faker preserved
use function Pest\Faker\fake; Import automatically removed
use function Pest\Laravel\{get, post}; Grouped imports automatically removed
use function Pest\Livewire\livewire; Import automatically removed

Silently Stripped (debug/dev-only)

These Pest methods are removed from the chain without emitting any output:

Modifier Reason
->dd() / ->ddWhen() / ->ddUnless() Debug — dump and die
->ray() Debug — Ray debugger
->json() Output modifier — no assertion equivalent
->defer() Timing modifier — no assertion equivalent

Converted to markTestSkipped ⚠️

These features have no PHPUnit equivalent and are converted to skipped tests with a review comment:

Pest Feature PHPUnit Output
arch() tests $this->markTestSkipped('Arch test not supported in PHPUnit: ...')
Higher-order it('...')->expect([...])->toBeUsed() $this->markTestSkipped('Arch test not supported in PHPUnit: ...')

Emits // TODO Comment ⚠️

These features emit a TODO comment because they require manual conversion:

Pest Feature TODO Comment
->sequence(...) // TODO(Pest): ->sequence() requires manual conversion to PHPUnit
->match(...) // TODO(Pest): ->match() requires manual conversion to PHPUnit
->scoped(...) // TODO(Pest): ->scoped() requires manual conversion to PHPUnit
->each(fn() => ...) (with closure) // TODO(Pest): ->each(closure) requires manual conversion to PHPUnit
->when(...) / ->unless(...) // TODO(Pest): ->when()/->unless() requires manual conversion to PHPUnit
Unknown ->toXxx() expectations // TODO(Pest): Unknown expectation ->toXxx() has no PHPUnit equivalent

Laravel / Livewire assert*() Methods ✅

When expect() wraps a Laravel TestResponse, Livewire Testable, or any object with assert*() methods, they are emitted as direct method calls on the subject:

This works automatically for all assert*() methods — no special mapping needed since these methods already throw PHPUnit assertions internally. Verified coverage includes:

Laravel TestResponse:

Category Methods
Status assertOk, assertCreated, assertNotFound, assertForbidden, assertUnauthorized, assertUnprocessable, assertStatus, assertSuccessful, assertNoContent
Content assertSee, assertDontSee, assertSeeText, assertSeeInOrder, assertSeeTextInOrder
JSON assertJson, assertExactJson, assertJsonFragment, assertJsonMissing, assertJsonStructure, assertJsonCount, assertJsonPath, assertJsonValidationErrors, assertJsonMissingValidationErrors
Redirects assertRedirect, assertRedirectContains, assertRedirectToRoute, assertLocation
Headers assertHeader, assertHeaderMissing
Validation assertValid, assertInvalid, assertSessionHasErrors
Session assertSessionHas, assertSessionHasAll, assertSessionMissing
Views assertViewIs, assertViewHas, assertViewHasAll, assertViewMissing
Cookies assertCookie, assertCookieMissing, assertCookieExpired
Downloads assertDownload

Livewire Testable:

Category Methods
Content assertSee, assertDontSee, assertSeeHtml, assertDontSeeHtml, assertSeeInOrder
Properties assertSet, assertNotSet, assertCount
Events assertDispatched, assertNotDispatched
Validation assertHasErrors, assertHasNoErrors
Navigation assertRedirect, assertRedirectToRoute, assertNoRedirect
Other assertStatus, assertForbidden, assertUnauthorized, assertViewHas, assertViewIs, assertFileDownloaded

Non-assert methods in the chain (like followRedirects(), set(), call()) are preserved naturally as chained method calls.

Custom Expectations (expect()->extend()) ✅

Custom expectations defined via expect()->extend('name', fn) are parsed and inlined at call sites:

Supports:

Not Supported

Pest Feature Notes
Higher-order test methods (e.g. it('...')->assertTrue()) Not converted
beforeAll/afterAll inside describe() No clean PHPUnit equivalent without multiple classes

Limitations

Development

Adding test fixtures

Test fixtures live in tests/Rector/Fixture/ as .php.inc files with the format:

If the file should remain unchanged (no Pest code), omit the ----- separator.

License

MIT. See LICENSE.

Credits

Built by Helge Sverre on top of Rector and nikic/php-parser.


All versions of pest-to-phpunit with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
rector/rector Version ^2.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package helgesverre/pest-to-phpunit contains the following files

Loading the files please wait ...