Pest is PHPUnit underneath, which is the good news

The runner, the assertions and the extensions are PHPUnit’s, which means adopting it is a syntax decision rather than a testing-framework migration.

it('rejects a negative quantity', function () {
    expect(fn () => new OrderLine(sku: 'A', quantity: -1))
        ->toThrow(InvalidArgumentException::class);
});

dataset('invalid quantities', [-1, 0, PHP_INT_MIN]);

// and the mixed codebase, which is supported:
// tests/Unit/OrderTest.php   — a PHPUnit class
// tests/Unit/LineTest.php    — Pest, in the same suite

Both styles running in one suite is what makes a trial cheap and what makes a half-finished migration comfortable enough to leave — which is the actual risk. The tooling gap is the other cost: static analysis, coverage annotations and IDE navigation all understand the class form better, and the difference narrows every year.