ワンクリックで
testo-coverage
// Configure code coverage in Testo via CodecovPlugin, choose coverage level (Line/Branch/Path), wire up reports (Clover/Cobertura/PHPUnit XML), and use
// Configure code coverage in Testo via CodecovPlugin, choose coverage level (Line/Branch/Path), wire up reports (Clover/Cobertura/PHPUnit XML), and use
Stabilize flaky Testo tests with
Migrate an existing PHPUnit test suite to Testo. 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.
Author a Testo plugin — event listeners, interceptors, custom container bindings, or new test attributes. Use when the user wants to extend Testo's behaviour (custom reporters, lifecycle hooks across the suite, attribute-driven middleware, integrating an external system) rather than writing a single test.
Write or modify tests in a project that uses the Testo PHP testing framework. Use when adding a
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".
Parameterize Testo tests with
| name | testo-coverage |
| description | Configure code coverage in Testo via CodecovPlugin, choose coverage level (Line/Branch/Path), wire up reports (Clover/Cobertura/PHPUnit XML), and use |
Coverage is opt-in via the CodecovPlugin in testo.php. The plugin needs:
Line, Branch, or Path (each adds cost and information).Fetch https://php-testo.github.io/llms.txt (and llms-full.txt if you need plugin wiring detail)
before editing — exact class names and constructor parameters are authoritative there.
testo.phpuse Testo\Application\Config\ApplicationConfig;
use Testo\Codecov\CodecovPlugin;
use Testo\Codecov\Config\CoverageLevel;
use Testo\Codecov\Report\CloverReport;
use Testo\Codecov\Report\CoberturaReport;
use Testo\Codecov\Report\PhpUnitXmlReport;
return new ApplicationConfig(
src: ['src'],
suites: [/* ... */],
plugins: [
new CodecovPlugin(
level: CoverageLevel::Line,
reports: [
new CloverReport(__DIR__ . '/runtime/clover.xml', 'MyProject'),
new CoberturaReport(__DIR__ . '/runtime/cobertura.xml'),
new PhpUnitXmlReport(outputDir: __DIR__ . '/runtime/coverage-xml'),
],
),
],
);
Then enable on the CLI:
vendor/bin/testo --coverage
vendor/bin/testo --no-coverage # explicit off, overrides config
| Level | Cost | When |
|---|---|---|
Line | Low | Default for CI gates. |
Branch | Medium | When you need to be sure if/match/?: branches are exercised. |
Path | High | Mutation testing setup, exhaustive analysis. Usually local-only. |
Don't ship Path on every CI run — it's the slowest. Reserve it for mutation testing or scheduled jobs.
#[Covers] and #[CoversNothing]Declare which production classes a test exercises. This scopes coverage reports and surfaces dead tests.
use Testo\Codecov\Covers;
use Testo\Codecov\CoversNothing;
#[Test]
#[Covers(UserService::class)] // class-level — applies to every test in the class
final class UserServiceTest { /* ... */ }
#[Test]
#[Covers(OrderTotal::class)]
#[Covers(TaxCalculator::class)] // repeatable: multiple covered targets
final class CheckoutTest { /* ... */ }
#[Test]
#[CoversNothing] // explicitly exclude from coverage attribution
final class SmokeTest { /* ... */ }
Rules (this is project policy in many Testo codebases — confirm before changing):
#[Covers] when every test in the class covers the same production class. This is the default.#[Covers] when tests in the same class cover different classes.#[Covers('App\\helpers\\format_money')] (verify against llms.txt for the version in use).| Report | Format | Typical consumer |
|---|---|---|
CloverReport | Clover XML | Codecov, Coveralls, GitHub coverage diffs. |
CoberturaReport | Cobertura XML | GitLab/Jenkins coverage UI. |
PhpUnitXmlReport | PHPUnit-style coverage XML | Infection (mutation testing). |
For Infection, point infection.json's coverage.path at the directory you gave to PhpUnitXmlReport.
xdebug.mode=coverage (or PCOV is loaded). Testo skips the driver if neither is available.clover.xml empty? Suite-level finder probably excludes the src directory you expected — verify the FinderConfig covers it.#[Covers(SomeInterface::class)] — point at concrete classes that own the executable code.#[Covers] and #[CoversNothing] on the same class/method — pick one.