PHPackages                             chqthomas/approval-tests - 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. chqthomas/approval-tests

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

chqthomas/approval-tests
========================

Approval Tests Library for PHP

v0.1.0-alpha(1y ago)11.5k↓66.7%MITPHPPHP &gt;=7.4CI passing

Since Feb 16Pushed 1y ago1 watchersCompare

[ Source](https://github.com/ChqThomas/approval-tests-php)[ Packagist](https://packagist.org/packages/chqthomas/approval-tests)[ RSS](/packages/chqthomas-approval-tests/feed)WikiDiscussions main Synced 1mo ago

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

PHP Approval Tests
==================

[](#php-approval-tests)

A PHP library for approval testing. This approach allows you to verify complex results by comparing them with approved versions, making it ideal for testing outputs that are difficult to assert traditionally (e.g., HTML, JSON, XML, or binary files).

Warning

This library is still in development. It is not recommended for production use. Many features are still missing, and the API may change.

Table of Contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Basic Usage](#basic-usage)
    - [Simple Test](#simple-test)
    - [Structured Data Test](#structured-data-test)
- [Specialized Verifications](#specialized-verifications)
    - [HTML](#html)
    - [JSON](#json)
    - [XML](#xml)
    - [CSV](#csv)
    - [Binary Files](#binary-files)
- [Advanced Features](#advanced-features)
    - [Tests with Data Providers](#tests-with-data-providers)
    - [Verify All Combinations](#verify-all-combinations)
- [Configuration](#configuration)
    - [PHPUnit Bootstrap Configuration](#phpunit-bootstrap-configuration)
    - [Set a Custom Reporter](#set-a-custom-reporter)
    - [Use a Custom Object Formatter](#use-a-custom-object-formatter)
    - [Custom Namer](#custom-namer)
    - [Auto-Approve Snapshots](#auto-approve-snapshots)
- [Scrubbers](#scrubbers)
    - [JSON Scrubbing](#json-scrubbing)
        - [Ignore JSON Members](#ignore-json-members)
        - [Scrub JSON Members](#scrub-json-members)
    - [XML Scrubbing](#xml-scrubbing)
    - [Regex Scrubbing](#regex-scrubbing)
    - [Custom Scrubber](#custom-scrubber)
- [Maintenance](#maintenance)
    - [Cleanup Received Files](#cleanup-received-files)
    - [Detect Orphaned Files](#detect-orphaned-files)
- [Reporters](#reporters)
    - [CLI Reporter](#cli-reporter)
    - [Diff Reporter](#diff-reporter)
    - [Composite Reporter](#composite-reporter)
- [Symfony Integration](#symfony-integration)
- [Best Practices](#best-practices)
- [Contributing](#contributing)
- [License](#license)

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

[](#installation)

Install the library via Composer:

```
composer require chqthomas/approval-tests
```

Basic Usage
-----------

[](#basic-usage)

### Simple Test

[](#simple-test)

Verify a simple string output:

```
use ChqThomas\ApprovalTests\Approvals;

public function testSimpleString(): void
{
    Approvals::verify("Hello World");
}
```

The first time this runs, it generates a `.received.txt` file. Approve it by renaming it to `.approved.txt` or use auto-approval (see below).

### Structured Data Test

[](#structured-data-test)

Verify complex data structures like arrays or objects:

```
public function testArray(): void
{
    $data = [
        'name' => 'John Doe',
        'age' => 30,
        'roles' => ['admin', 'user']
    ];
    Approvals::verify($data);
}
```

Specialized Verifications
-------------------------

[](#specialized-verifications)

The library supports specific formats with dedicated methods:

### HTML

[](#html)

Verify HTML content with automatic formatting:

```
public function testHtml(): void
{
    $html = 'Hello World';
    Approvals::verifyHtml($html);
}
```

### JSON

[](#json)

Verify JSON with pretty-printing and scrubbing:

```
public function testJson(): void
{
    $json = '{"name":"John","age":30}';
    Approvals::verifyJson($json); // Automatically formatted
}
```

### XML

[](#xml)

Verify XML with formatting:

```
public function testXml(): void
{
    $xml = 'John';
    Approvals::verifyXml($xml);
}
```

### CSV

[](#csv)

Verify CSV content:

```
public function testCsv(): void
{
    $csv = "name,age\nJohn,30\nJane,25";
    Approvals::verifyCsv($csv);
}
```

### Binary Files

[](#binary-files)

Verify binary content (e.g., images):

```
public function testBinaryFile(): void
{
    Approvals::verifyBinaryFile('path/to/image.png', 'png');
}
```

Advanced Features
-----------------

[](#advanced-features)

### Tests with Data Providers

[](#tests-with-data-providers)

Use PHPUnit data providers for parameterized tests:

```
/**
 * @dataProvider provideTestData
 */
public function testWithDataProvider(array $data, string $expected): void
{
    $result = processData($data);
    Approvals::verify($result);
}

public static function provideTestData(): array
{
    return [
        'case1' => [['input' => 1], 'output1'],
        'case2' => [['input' => 2], 'output2'],
    ];
}
```

### Verify All Combinations

[](#verify-all-combinations)

Test all combinations of inputs:

```
public function testAllCombinations(): void
{
    $operations = ['+', '-', '*', '/'];
    $numbers = [1, 2, 3];

    Approvals::verifyAllCombinations(
        function($op, $a, $b) {
            switch($op) {
                case '+': return $a + $b;
                case '-': return $a - $b;
                case '*': return $a * $b;
                case '/': return $b != 0 ? $a / $b : 'Division by zero';
            }
        },
        [$operations, $numbers, $numbers]
    );
}
```

Configuration
-------------

[](#configuration)

Customize the library’s behavior via the `Configuration` class:

### PHPUnit Bootstrap Configuration

[](#phpunit-bootstrap-configuration)

Create a `tests/bootstrap.php` file to configure the library globally for all your tests:

```

    John
    2024-01-01T12:00:00
    550e8400-e29b-41d4-a716-446655440000

XML;

    // Custom scrubber for XML
    Approvals::verifyXml($xml, XmlScrubber::create()
        ->addScrubber(fn($content) => preg_replace('/John/', '[NAME]', $content)));
}
```

### Regex Scrubbing

[](#regex-scrubbing)

Use regular expressions for generic scrubbing:

```
public function testRegexScrubbing(): void
{
    $json =  '"id": "MATCHED"'])));
}
```

### Custom Scrubber

[](#custom-scrubber)

Create a custom scrubber for any content:

```
use ChqThomas\ApprovalTests\Scrubber\AbstractScrubber;

class MyScrubber extends AbstractScrubber
{
    public function scrub(string $content): string
    {
        // Apply base scrubbers first (GUIDs, dates)
        $content = $this->scrubGuids($content);
        $content = $this->scrubDates($content);

        // Add your custom rules
        $content = preg_replace('/secret-\d+/', '[SECRET]', $content);

        // Apply additional scrubbers
        return $this->applyAdditionalScrubbers($content);
    }
}

// Usage
public function testWithCustomScrubber(): void
{
    $content = "ID: secret-123\nDate: 2024-01-01";

    Approvals::verifyWithExtension(
        $content,
        "txt",
        MyScrubber::create()
            ->addScrubber(fn($text) => str_replace('ID:', 'Reference:', $text))
    );
}
```

Maintenance
-----------

[](#maintenance)

### Cleanup Received Files

[](#cleanup-received-files)

Remove redundant `.received` files:

```
use ChqThomas\ApprovalTests\ApprovalMaintenance;

ApprovalMaintenance::cleanUpReceivedFiles(__DIR__ . '/tests/approvals');
```

### Detect Orphaned Files

[](#detect-orphaned-files)

Find `.approved` files without associated tests:

```
$orphanedFiles = ApprovalMaintenance::findOrphanedApprovedFiles(__DIR__ . '/tests');
```

Reporters
---------

[](#reporters)

Customize how differences are reported:

### CLI Reporter

[](#cli-reporter)

Default reporter for terminal output:

```
use ChqThomas\ApprovalTests\Reporter\CliReporter;

Configuration::getInstance()->setReporter(new CliReporter());
```

### Diff Reporter

[](#diff-reporter)

Show differences using a diff format:

```
use ChqThomas\ApprovalTests\Reporter\DiffReporter;

Configuration::getInstance()->setReporter(new DiffReporter());
```

### Composite Reporter

[](#composite-reporter)

Combine multiple reporters:

```
use ChqThomas\ApprovalTests\Reporter\CompositeReporter;

$reporter = new CompositeReporter([
    new CliReporter(),
    new DiffReporter()
]);
Configuration::getInstance()->setReporter($reporter);
```

Symfony Integration
-------------------

[](#symfony-integration)

Use with Symfony’s DomCrawler for web testing:

```
use ChqThomas\ApprovalTests\Symfony\ApprovalCrawlerAssertionsTrait;

class MyWebTest extends WebTestCase
{
use ApprovalCrawlerAssertionsTrait;

    public function testPageContent(): void
    {
        $client = static::createClient();
        $client->request('GET', '/');
        self::verifySelectorHtml('#main-content');
    }
}
```

Best Practices
--------------

[](#best-practices)

1. Store `.approved` files in version control.
2. Use scrubbers for variable data (e.g., dates, IDs).
3. Regularly clean up `.received` files.
4. Check for orphaned `.approved` files.
5. Use descriptive test names for clear file naming.

Contributing
------------

[](#contributing)

Contributions are welcome! To contribute:

1. Fork the project.
2. Create a feature branch.
3. Submit a pull request.

License
-------

[](#license)

MIT License

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance44

Moderate activity, may be stable

Popularity21

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity24

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.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

456d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7740151?v=4)[Thomas Choquet](/maintainers/ChqThomas)[@ChqThomas](https://github.com/ChqThomas)

---

Top Contributors

[![ChqThomas](https://avatars.githubusercontent.com/u/7740151?v=4)](https://github.com/ChqThomas "ChqThomas (26 commits)")

---

Tags

approval-testingassertion-libraryphpunitsnapshot-testing

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/chqthomas-approval-tests/health.svg)

```
[![Health](https://phpackages.com/badges/chqthomas-approval-tests/health.svg)](https://phpackages.com/packages/chqthomas-approval-tests)
```

###  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)
