Skip to content

Repository files navigation

TESTO

The PHP Testing Framework You Control

DocumentationSupport on Boosty

Vibe IndexPsalm LevelType CoveragecodecovMutation testing badge


Testo is an extensible testing framework built on a lightweight core with a middleware system. It gives you full control over your testing environment while keeping the familiar PHP syntax you already know.

Get Started

Installation

composer require --dev testo/testo *

PHPLatest Version on PackagistLicenseTotal Destroys

Configuration

The fastest way to set up Testo in your project is the built-in init command:

vendor/bin/testo init

It will:

  • detect your src/ directory (or prompt for it),
  • create tests/Unit/ if missing,
  • generate a minimal testo.php next to your composer.json,
  • register composer test and composer test:<suite> scripts.

For a sub-app layout, point it at the project root: vendor/bin/testo init --path=app.

Tuning testo.php manually

testo.php is plain PHP returning an ApplicationConfig — edit it freely to add suites, plugins, or coverage. A typical setup looks like:

<?phpdeclare(strict_types=1);
useTesto\Application\Config\ApplicationConfig;
useTesto\Application\Config\Plugin\SuitePlugins;
useTesto\Application\Config\SuiteConfig;
useTesto\Bench\BenchmarkPlugin;
useTesto\Inline\InlineTestPlugin;
returnnewApplicationConfig(
src: ['src'],
suites: [
newSuiteConfig(
name: 'Sources',
location: ['src'],
// Only Benchmarking and Inline Tests for Source files
plugins: SuitePlugins::only(
newInlineTestPlugin(),
newBenchmarkPlugin(),
),
),
newSuiteConfig(
name: 'Unit',
location: ['tests/Unit'],
),
],
);

If no testo.php is present at all, Testo falls back to running every test under the tests/ folder.

Running Tests

To run your tests, execute:

composer test

…or call the binary directly if you skipped init / didn't register the script:

vendor/bin/testo

You can also run a single suite by name (one script per detected suite is registered by init):

composer test:unit
composer test:integration

Writing Your First Test

Create a test class in the configured test directory (e.g., tests/CalculatorTest.php):

<?phpdeclare(strict_types=1);
namespaceTests;
useTesto\Assert;
useTesto\Assert\ExpectException;
useTesto\Retry;
useTesto\Test;
#[Test]
finalclass CalculatorTest
{
publicfunctiondividesNumbers(): void
{
$result = 10 / 2;
Assert::same($result, 5.0);
Assert::notSame($result, 5); // Types matter!
}
#[Retry(maxAttempts: 3)]
publicfunctionflakyApiCall(): void
{
// Retries up to 3 times if test fails$response = $this->makeExternalApiCall();
Assert::same($response->status, 200);
}
#[ExpectException(\RuntimeException::class)]
publicfunctionthrowsException(): void
{
thrownew \RuntimeException('Expected error');
}
}

What to note:

  • Use the #[Test] attribute to mark test methods or classes
  • Test classes don't need to extend any base class
  • Use Assert class for assertions (same, true, false, null, contains, instanceOf, etc.)
  • Testo provides multiple attributes to extend testing capabilities (retry policies, exception handling, and more)

IDE Support

Testo comes with the IDEA plugin Testo.

VersionRatingDownloads

About

The Testing Framework

Topics

Resources

Code of conduct

Contributing

Stars

207 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages