PHPackages                             elazar/phantestic - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. elazar/phantestic

ActiveLibrary[Testing &amp; Quality](/categories/testing)

elazar/phantestic
=================

A small PHP testing framework

0.3.0(10y ago)0171BSD-2-ClausePHPPHP &gt;=5.5.0

Since Apr 21Pushed 10y ago1 watchersCompare

[ Source](https://github.com/elazar/phantestic)[ Packagist](https://packagist.org/packages/elazar/phantestic)[ RSS](/packages/elazar-phantestic/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (1)Dependencies (1)Versions (5)Used By (0)

elazar/phantestic
=================

[](#elazarphantestic)

A small PHP testing framework that aims to be simple, fast, modern, and flexible.

Currently in a very alpha state. Feel free to mess around with it, but expect things to break.

[![Build Status](https://camo.githubusercontent.com/d1dd625fe30cbcdb934ad9647d83aab1b6c3818567f72d1f86e2ec423398a75e/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f656c617a61722f7068616e7465737469632e737667)](http://travis-ci.org/elazar/phantestic)[![Code Climate](https://camo.githubusercontent.com/8d4fd1e0dc64436c8856f6777194246f121665a82a694d85e6dfa408a71f6a65/68747470733a2f2f636f6465636c696d6174652e636f6d2f6769746875622f656c617a61722f7068616e7465737469632f6261646765732f6770612e737667)](https://codeclimate.com/github/elazar/phantestic)

Installation
------------

[](#installation)

Use [Composer](https://getcomposer.org).

```
{
    "require-dev": {
        "elazar/phantestic": "^0.2"
    }
}
```

Components
----------

[](#components)

A **test loader** loads the tests to be run. It can be anything that implements [`\Traversable`](http://php.net/manual/en/class.traversable.php) (i.e. an instance of a class that implements [`\IteratorAggregate`](http://php.net/manual/en/class.iteratoraggregate.php) or [`\Iterator`](http://php.net/manual/en/class.iterator.php), such as [`\Generator`](http://php.net/manual/en/class.generator.php)) to allow loaded tests to be iterable.

The **test runner** uses the test loader to load tests, run them, and in the process emit multiple events that **test handlers** can intercept and act upon.

As an example, [`LocalRunner`](https://github.com/elazar/phantestic/blob/master/src/Runner/LocalRunner.php) runs tests in the same PHP process as the test runner. Its constructor accepts two arguments: the test loader to use and an array of test handler objects that implement [`HandlerInterface`](https://github.com/elazar/phantestic/blob/master/src/Handler/HandlerInterface.php).

When its `run()` method is called, [`LocalRunner`](https://github.com/elazar/phantestic/blob/master/src/Runner/LocalRunner.php) handles injecting an [event emitter](https://github.com/igorw/evenement/blob/master/src/Evenement/EventEmitterInterface.php) into the test handler objects, which enables those objects to register callbacks with the emitter for any events that may be relevant to them.

An example of a test handler is [`CliOutputHandler`](https://github.com/elazar/phantestic/blob/master/src/Handler/CliOutputHandler.php), which outputs the results of executing tests to `stdout` as they are received and a failure summary once all tests have been run.

Configuring a Runner
--------------------

[](#configuring-a-runner)

There is no stock test runner; one must be configured based on the needs of your project.

Here's a sample runner configuration.

```
$classmap_path = '../vendor/composer/autoload_classmap.php';
$loader = new \Phantestic\Loader\ClassmapFileObjectLoader($classmap_path);
$handlers = [ new \Phantestic\Handler\CliOutputHandler ];
$runner = new \Phantestic\Runner\LocalRunner($loader, $handlers);
$runner->run();
```

[`ClassmapFileObjectLoader`](https://github.com/elazar/phantestic/blob/master/src/Loader/ClassmapFileObjectLoader.php) locates tests based on the contents of a classmap file, such as the one generated by the `-o` flag of several [Composer](https://getcomposer.org) commands. By default, it looks for class files with names ending in `Test.php`, instantiates the classes, and invokes methods with names prefixed with `test`. Callbacks used to filter test methods based on file, class, and method names and to generate test case objects can be changed using the constructor parameters of [`ClassmapFileObjectLoader`](https://github.com/elazar/phantestic/blob/master/src/Loader/ClassmapFileObjectLoader.php).

Writing Tests
-------------

[](#writing-tests)

Theoretically, tests can be anything [callable](http://php.net/manual/en/language.types.callable.php). The test loader may restrict this to specific types of callables (e.g. [`ClassmapFileObjectLoader`](https://github.com/elazar/phantestic/blob/master/src/Loader/ClassmapFileObjectLoader.php) only supports instance methods). The test loader wraps test callbacks in an instance of a class implementing [`TestInterface`](https://github.com/elazar/phantestic/blob/master/src/Test/TestInterface.php), such as the default [`Test`](https://github.com/elazar/phantestic/blob/master/src/Test/Test.php) implementation.

Failures can be indicated by throwing an [exception](http://php.net/manual/en/language.exceptions.php). Other statuses can be indicated by throwing an instance of a subclass of [`Result`](https://github.com/elazar/phantestic/blob/master/src/Result/Result.php). [`Test`](https://github.com/elazar/phantestic/blob/master/src/Test/Test.php) [converts errors to exceptions](http://php.net/manual/en/class.errorexception.php#errorexception.examples) and considers any uncaught exception to indicate failure. Likewise, no exception being thrown indicates success.

```
// src/Adder.php
class Adder
{
    public function add($x, $y)
    {
        return $x + $y;
    }
}

// tests/AdderTest.php
class AdderTest
{
    public function testAdd()
    {
        $adder = new Adder;
        $result = $adder->add(2, 2);
        if ($result != 4) {
            throw new \RangeException('2 + 2 should equal 4');
        }
    }
}
```

Writing Test Handlers
---------------------

[](#writing-test-handlers)

Test handlers implement [`HandlerInterface`](https://github.com/elazar/phantestic/blob/master/src/Handler/HandlerInterface.php), which has a single method: `setEventEmitter()`. This method receives an instance of [`EventEmitterInterface`](https://github.com/igorw/evenement/blob/master/src/Evenement/EventEmitterInterface.php) as its only argument. Within its implementation of `setEventEmitter()`, a test handler can use this argument to register event callbacks. An example of this is below, taken from [`CliOutputHandler`](https://github.com/elazar/phantestic/blob/master/src/Handler/CliOutputHandler.php), which registers its own methods as callbacks for several events.

```
public function setEventEmitter(EventEmitterInterface $emitter)
{
    $emitter->on('phantestic.test.failresult', [$this, 'handleFail']);
    $emitter->on('phantestic.test.passresult', [$this, 'handlePass']);
    $emitter->on('phantestic.tests.before', [$this, 'beforeTests']);
    $emitter->on('phantestic.tests.after', [$this, 'afterTests']);
}
```

Supported events may vary depending on the test loader and runner in use.

### [`LocalRunner`](https://github.com/elazar/phantestic/blob/master/src/Runner/LocalRunner.php)

[](#localrunner)

- `phantestic.tests.before`: Before any tests are run, with the test runner as an argument
- `phantestic.tests.after`: After all tests are run, with the test runner as an argument
- `phantestic.test.before`: Before each test, with the test case and runner as arguments
- `phantestic.test.after`: After each test, with the test case and runner as arguments
- `phantestic.test.failresult`: When a test fails, with the test case and runner as arguments
- `phantestic.test.passresult`: When a test passes, with the test case and runner as arguments
- `phantestic.test.RESULT`: When a test has a result other than passing or failing where `RESULT` is the short name of the class extending [`Result`](https://github.com/elazar/phantestic/blob/master/src/Result/Result.php), with the test case and runner as arguments

### [`ClassmapFileObjectLoader`](https://github.com/elazar/phantestic/blob/master/src/Loader/ClassmapFileObjectLoader.php)

[](#classmapfileobjectloader)

- `phantestic.loader.loaded`: When a test case is loaded, with the test case and associated test class name and test method name as arguments

Differences from PHPUnit
------------------------

[](#differences-from-phpunit)

Tests may be instance methods of classes, but they don't have to be since individual tests can be anything callable. If you do choose to use instance methods for tests:

- There is no equivalent to `PHPUnit_Framework_TestCase`. You may create your own base class if you wish, but it is not required.
- There are no equivalents to `setUp()` or `tearDown()`. Consider using either `__construct()` and `__destruct()` or test handlers in conjunction with a loader that supports `phantestic.test.before` and `phantestic.test.after`.
- If you wish for tests to be located using the same criteria as PHPUnit and you're using Composer, just use [`ClassmapFileObjectLoader`](https://github.com/elazar/phantestic/blob/master/src/Loader/ClassmapFileObjectLoader.php) and specify only the classmap file path when instantiating it.
- Assertions are merely methods that throw exceptions if expected conditions are not met. Consider supplementary libraries like [those recommended for use with Peridot](https://github.com/peridot-php/peridot/wiki/Matchers).
- Mocking is not supported natively. Consider supplementary libraries like [Phake](https://github.com/mlively/phake) or [Mockery](https://github.com/padraic/mockery).
- Database seeding and assertions are not supported natively. Consider supplementary libraries like [Phactory](https://github.com/chriskite/phactory) or [Faker](https://github.com/fzaninotto/Faker).

###  Health Score

24

—

LowBetter than 31% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 96% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~91 days

Total

3

Last Release

3909d ago

PHP version history (2 changes)0.1.0PHP &gt;=5.4.2

0.2.0PHP &gt;=5.5.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/80dec604abed1b21daafc54c430468444a2ad163ad5f8229348b8d241b797778?d=identicon)[elazar](/maintainers/elazar)

---

Top Contributors

[![elazar](https://avatars.githubusercontent.com/u/15487?v=4)](https://github.com/elazar "elazar (72 commits)")[![leftees](https://avatars.githubusercontent.com/u/12038092?v=4)](https://github.com/leftees "leftees (2 commits)")[![robertology](https://avatars.githubusercontent.com/u/11565712?v=4)](https://github.com/robertology "robertology (1 commits)")

---

Tags

testingtestqa

### Embed Badge

![Health badge](/badges/elazar-phantestic/health.svg)

```
[![Health](https://phpackages.com/badges/elazar-phantestic/health.svg)](https://phpackages.com/packages/elazar-phantestic)
```

###  Alternatives

[mockery/mockery

Mockery is a simple yet flexible PHP mock object framework

10.7k526.2M27.0k](/packages/mockery-mockery)[phpmetrics/phpmetrics

Static analyzer tool for PHP : Coupling, Cyclomatic complexity, Maintainability Index, Halstead's metrics... and more !

2.6k15.4M367](/packages/phpmetrics-phpmetrics)[php-mock/php-mock

PHP-Mock can mock built-in PHP functions (e.g. time()). PHP-Mock relies on PHP's namespace fallback policy. No further extension is needed.

37419.9M125](/packages/php-mock-php-mock)[brain/monkey

Mocking utility for PHP functions and WordPress plugin API

34214.3M485](/packages/brain-monkey)[ta-tikoma/phpunit-architecture-test

Methods for testing application architecture

10958.3M21](/packages/ta-tikoma-phpunit-architecture-test)[php-mock/php-mock-phpunit

Mock built-in PHP functions (e.g. time()) with PHPUnit. This package relies on PHP's namespace fallback policy. No further extension is needed.

1719.0M545](/packages/php-mock-php-mock-phpunit)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
