PHPackages                             pitchart/phlunit - 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. pitchart/phlunit

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

pitchart/phlunit
================

Fluent assertions for PHP

1251[2 issues](https://github.com/pitchart/phlunit/issues)PHP

Since Mar 16Pushed 3y ago1 watchersCompare

[ Source](https://github.com/pitchart/phlunit)[ Packagist](https://packagist.org/packages/pitchart/phlunit)[ RSS](/packages/pitchart-phlunit/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (5)Used By (0)

[![Build Status](https://camo.githubusercontent.com/a1783bff6f2878e0ea625846923f905537399a24c2c517c68566eb35461444e6/68747470733a2f2f7472617669732d63692e636f6d2f70697463686172742f70686c756e69742e7376673f6272616e63683d6d6173746572)](https://travis-ci.com/pitchart/phlunit)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/b28f407f97a45b04f86a432cb8ef22ecc62695fc25ddd1fc99af26c89bf31604/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f70697463686172742f70686c756e69742f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/pitchart/phlunit/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/a777b1357c5199f12a3d073e6d1ffd5b5943e1305d3a24532ae2218a692abb3e/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f70697463686172742f70686c756e69742f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/pitchart/phlunit/?branch=master)

Phlunit: PHP Fluent Unit Testing
================================

[](#phlunit-php-fluent-unit-testing)

`Check::that(tdd())->with($phlunit)->isAnInstanceOf(Awesomeness::class);`

***Fluent assertions for phpunit.***

Why ?
-----

[](#why-)

`Phlunit` will make your tests:

- **fluent to write:** juste type `Check::that($sut)` and let auto-completion guide you.
- **fluent to read:** very close to plain English, making it easier for non-technical people to read test code.
- **fluent to troubleshoot:** every failing check throws an Exception with a clear message status to ease your TDD experience.
- **less error-prone:** no more confusion about the order of the "expected" and "actual" values.

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

[](#installation)

```
composer require --dev pitchart/phlunit
```

Write checks
------------

[](#write-checks)

Write test cases and test methods as usual, just switch to `Check::that()` to write your assertions :

```
use Pitchart\Phlunit\Check;

$integers = [1, 2, 3, 4, 5, 42];
Check::that($integers)->contains(2, 3, 42);

$heroes = "Batman and Robin";
Check::that($heroes)
    ->startsWith("Batman")
    ->contains("Robin")
;

// Collection checks
Check::that([0, 1, 2])
    ->isACollectionOf('integer')
    ->hasElementAt(1)
    ->and->hasNoElementAt(12)
    ->hasLength(3)
    ->hasNotLength(12)
    ->contains(1, 2)
    ->isSubsetOf(0, 1, 2, 3, 4)
    ->containsNoDuplicateItem()
;

// PSR-7 ResponseInterface checks
$response = (new Response(200))
    ->withHeader('xxx-header', 'xxx-header-value')
    ->withBody(Utils::streamFor('{"name": "Batman", "city": "Gotham City"}'))
;

Check::that($response)
    ->asJson()
        ->matchesSchema(['type' => 'object', 'required' => ['name'], 'properties' => ['name' => ['type' => 'string']]]);
```

`Phlunit` provides checks for the following types and classes :

- string, boolean, integer, float, array
- xml and json formats
- iterable
- callable
- Throwable
- ResponseInterface (PSR-7)
- DateTimeInterface

Syntactic sugar
---------------

[](#syntactic-sugar)

Improve readability using `that()` and `andThat()` methods :

```
Check::thatCall([$spiderman, 'saveGotham'])->with('batman', 'superman')
    ->throws(\LogicException::class)
    ->that()->isDescribedBy("Sorry, we are not in the same univers!");

Check::that($batman->getFirstname())->isEqualTo('Bruce')
    ->andThat($batman->getLastname())->isEqualTo('Wayne');
```

Need more checks ?
------------------

[](#need-more-checks-)

### Use custom constraints

[](#use-custom-constraints)

Write custom phpunit constraints and use them thanks to methods `is()`, `has()`, `isNot()` or `hasNot()` :

```
class CustomConstraint extends Constraint
{
    //...
}

Check::that($sut)->is(new CustomConstraint());
```

### Create custom Check class

[](#create-custom-check-class)

```
class CustomClassCheck implements FluentCheck
{
    //...
}

// Register your custom checks for dedicated classes in phpunit's bootstrap file
Check::registerChecksFor(Custom::class, CustomClassChecks::class);

//
Check::that(Check::that(new Custom))->isAnInstanceOf(CustomClassChecks::class);
```

Test data builder
-----------------

[](#test-data-builder)

`Phlunit` provides a simple and extensible way to implement the [test data builder pattern](http://www.natpryce.com/articles/000714.html).

Here is the recommended way to use it, to not break the fluent experience:

```
use Pitchart\Phlunit\Builder;

class HeroBuilder extends Builder
{
    protected function __construct(array $arguments)
    {
        parent::__construct(Hero::class, $arguments);
    }

    public function build(): Hero
    {
        return $this->buildInstance();
    }

    public static function create(): self
    {
        return new self([
            'name' => 'Batman',
            'firstname' => 'Bruce',
            'lastname' => 'Wayne',
        ]);
    }

    public static function batman(): self
    {
        return self::create();
    }
}

// Use it in your test cases:
$batman = HeroBuilder::batman()->build();

$superman = HeroBuilder::create()
    ->withName('Superman')
    ->andFirstname('Clark')
    ->andLastname('Kent')
    ->build()
;
```

Expect exceptions
-----------------

[](#expect-exceptions)

`Phlunit` provides a fluent way to expect exception from your code, using the `Expect` class:

```
use Pitchart\Phlunit\Expect;

public function test_an_exception_is_thrown()
{
    Expect::after($this)
        ->anException(\InvalidArgumentException)
        ->describedBy('An exception message')
        ->havingCode(42);

    // Act
}
```

Credits
-------

[](#credits)

This package has been mainly inspired by [NFluent](http://www.n-fluent.net/) and [AssertJ](https://joel-costigliola.github.io/assertj/)

Thanks to [Bruno Boucard](https://github.com/boucardbruno) for the inspiration.

Licence
-------

[](#licence)

The [MIT Licence](LICENCE.md)

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance0

Infrequent updates — may be unmaintained

Popularity17

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% 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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/3d434eb5aaedc60d5fb046facaf6445f1f1e52260d6776e3af30f1a7541d6385?d=identicon)[pitchart](/maintainers/pitchart)

---

Top Contributors

[![pitchart](https://avatars.githubusercontent.com/u/2943883?v=4)](https://github.com/pitchart "pitchart (85 commits)")

---

Tags

fluentfluent-testingphpphpunitphpunit-assertionstdd

### Embed Badge

![Health badge](/badges/pitchart-phlunit/health.svg)

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

###  Alternatives

[phpspec/prophecy

Highly opinionated mocking framework for PHP 5.3+

8.5k551.7M682](/packages/phpspec-prophecy)[brianium/paratest

Parallel testing for PHP

2.5k118.8M754](/packages/brianium-paratest)[beberlei/assert

Thin assertion library for input validation in business models.

2.4k96.9M570](/packages/beberlei-assert)[mikey179/vfsstream

Virtual file system to mock the real file system in unit tests.

1.4k108.0M2.7k](/packages/mikey179-vfsstream)[orchestra/testbench

Laravel Testing Helper for Packages Development

2.2k39.1M32.1k](/packages/orchestra-testbench)[phpspec/phpspec

Specification-oriented BDD framework for PHP 7.1+

1.9k36.7M3.1k](/packages/phpspec-phpspec)

PHPackages © 2026

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