with one click
testo-benchmarks
Write or tune Testo performance benchmarks with
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Write or tune Testo performance benchmarks with
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Migrate an existing PHPUnit (or Pest) test suite to Testo — via the Rector bridge, via AI-agent rewriting, or a combination. Use when the user says "migrate from PHPUnit", "port phpunit tests", "convert TestCase to Testo", or has files extending PHPUnit\Framework\TestCase that need to move to Testo's attribute-based style.
Set up or edit `testo.php` — the Testo application config. Use when the user is bootstrapping a project (including running `vendor/bin/testo init`), adding/removing a suite, scoping a finder, wiring an application-wide plugin (coverage, JUnit), or asking "where do I configure Testo" / "how do I initialize Testo".
Report and raise line coverage on a Testo project — collect coverage once, aggregate the Clover report into a ranked, LLM-friendly work-list, then optionally write tests for the least-covered files with subagents. Use both for read-only coverage questions and for improving coverage. Triggers are "increase coverage", "improve test coverage", "cover untested code", "find uncovered lines", "raise the coverage percentage", "what isn't tested", "what's our test coverage", "coverage status/report", "how well tested is X", "is X covered".
Write or modify tests in a project that uses the Testo PHP testing framework. Use when adding a
Author a Testo plugin — interceptors (middleware), event listeners, container bindings, custom attributes, or full test-environment provisioning. Use when the user wants to extend how Testo runs tests (wrap every test, provision a database/service, custom reporters, attribute-driven behaviour, integrating an external system) rather than writing a single test.
Run mutation testing on a Testo project with Infection (via testo/bridge-infection), collect surviving mutants efficiently, and kill them by strengthening tests. Use when the user asks about "mutation testing", "infection", "MSI", "mutation score", "escaped mutants", "kill mutants", or wants to measure how good the tests really are.
| name | testo-benchmarks |
| description | Write or tune Testo performance benchmarks with |
#[Bench])#[Bench] runs a method many times, collects timing statistics, and reports
Mean, Median, RStDev, with outlier rejection. The stability target is RStDev < 2% —
above that, the result is noisy and shouldn't be used to draw conclusions.
Requires the BenchmarkPlugin to be enabled for the suite. Fetch
https://php-testo.github.io/llms.txt for the current #[Bench] parameter list — they evolve.
<?php
declare(strict_types=1);
namespace App\Bench;
use Testo\Bench;
final class SerializationBench
{
#[Bench(
callables: [
'json_encode' => 'json_encode',
'native_serial' => 'serialize',
'custom' => [self::class, 'customEncode'],
],
arguments: [['a' => 1, 'b' => [2, 3, 4], 'c' => 'x']],
calls: 1000,
iterations: 5,
)]
public static function encode(): void
{
// Body is unused when `callables` is set — the listed callables are compared head-to-head.
}
public static function customEncode(array $data): string
{
return MyEncoder::encode($data);
}
}
Key parameters:
callables — map of label => callable to compare. Use it for A/B comparisons.arguments — array of positional arguments, applied to every callable.calls — invocations per iteration (the inner loop). Increase until per-iteration time is well above timer resolution.iterations — number of iterations (the outer loop). Drives the statistics (Mean/Median/RStDev).Benches are slow and noise-sensitive, so they shouldn't run on every testo invocation. Filter by type:
vendor/bin/testo --type=!bench # everything except benches
vendor/bin/testo --type=bench # only benches
--type is repeatable and !-prefixed values exclude (exclusion wins). Putting benches in their own SuiteConfig (with BenchmarkPlugin, enabled per suite) and running --suite=Bench works too.
callables. Don't bench json_encode($small) against serialize($large).When reporting comparison results, always include RStDev for each variant. A "30% faster" claim with 8% RStDev is noise.
#[Test] or #[TestInline] — keep benchmark classes separate.