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

ActiveLibrary

ahj/approval-tests
==================

Approval Tests

35PHP

Since Apr 6Pushed 5y ago1 watchersCompare

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

READMEChangelogDependenciesVersions (1)Used By (0)

 [ ![GitHub Build Status](https://github.com/alexandrajulius/approval-tests/actions/workflows/ci.yml/badge.svg) ](https://github.com/alexandrajulius/approval-tests/actions) [ ![Scrutinizer Code Quality](https://camo.githubusercontent.com/5bff1ddf7daee8f9f9a6aa8f61757e064f97994a0272e6a73e82a1535f450849/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f616c6578616e6472616a756c6975732f617070726f76616c2d74657374732f6261646765732f636f7665726167652e706e673f623d6d61696e) ](https://scrutinizer-ci.com/g/alexandrajulius/approval-tests/?branch=main) [ ![Scrutinizer Code Coverage](https://camo.githubusercontent.com/a529f9c2594315901843570296d1221def21f809526a7db8330713f469d4e06a/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f616c6578616e6472616a756c6975732f617070726f76616c2d74657374732f6261646765732f7175616c6974792d73636f72652e706e673f623d6d61696e) ](https://scrutinizer-ci.com/g/alexandrajulius/approval-tests/?branch=main) [ ![Approval Tests on packagist.org](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667) ](https://packagist.org/packages/ahj/approval-tests)

Approval Tests
==============

[](#approval-tests)

Why to use Approval Tests
-------------------------

[](#why-to-use-approval-tests)

Given you have (possibly legacy) code,
and you want to cover it with regression tests,
and you don't want to specify the output for each input in your unit tests,
and you don't want to adjust all the tested output after you changed the logic,
then you should use Approval Tests.

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

[](#installation)

```
composer require ahj/approval-tests --dev

```

Usage
-----

[](#usage)

Find an example on how to do Approval Testing under [/tests/Example](https://github.com/alexandrajulius/approval-tests/tree/main/tests/Example).

Create a test with phpunit, specify the input for your logic, store the output in a variable and pass it into
`Approvals::create()->verifyList($input, $output)`:

```
public function testUpdateQuality(): void
{
    $input = [
        new Item('foo', 0, 1),
    ];

    $output = (new GildedRose())->updateQuality($input);

    Approvals::create()->verifyList($input, $output);
}
```

`verifyList($input, $output)` will create a map of the received data and compare it to the previous version of this data by performing an `Assert::assertEquals($approved, $received)`.

Then run phpunit:

```
$ vendor/bin/phpunit tests

```

Then you will see a new directory in your test directory that contains two files:

```
/approval
  |__ approved.txt
  |__ received.txt

```

The `approved.txt` is initially empty.
In the `received.txt` you will find the `$input` mapped to the `$output` such as:

```
[foo, 0, 1] -> [foo, -1, 0]

```

Approve the `$output` by copying the content of `received.txt` to `approved.txt` or use the command from your console:

```
$ mv tests/Example/approval/received.txt tests/Example/approval/approved.txt

```

[![Screenshot 2021-03-27 at 09 46 18](https://user-images.githubusercontent.com/23189414/112715691-1f12a200-8ee2-11eb-9ef5-89d8d4eed9d3.png)](https://user-images.githubusercontent.com/23189414/112715691-1f12a200-8ee2-11eb-9ef5-89d8d4eed9d3.png)

When you run your test again, the `received.txt` will be gone, and you will have your test output in the `approval.txt`. Next you will just add more cases to your `$input` array in your test and approve the results. No need to specify any output manually :)

### Options

[](#options)

Pass an empty array as `$input` if your logic doesn't require input:

```
    Approvals::create()->verifyList([], $output);
```

In the `received.txt` you will only show the `$output` such as:

```
[foo, -1, 0]

```

Pass `$plain = true` as third argument to `verifyList()` in order to have non formated output in the `received.txt`:

```
    Approvals::create()->verifyList([], $output, true);
```

Depending on the type of `$output` there will either be a plain or json encoded string in the `received.txt`. For objects or arrays it will be:

```
{"dirPath":"bar","fileNumber":10,"randomList":[]},{"dirPath":"bar","fileNumber":100,"randomList":[]}

```

For a string it will be:

```
+--------------+-------------+--------+--------+------+-----+------------+---------+---------+---------+---------+---------+--------+-------+
| benchmark    | subject     | groups | params | revs | its | mem_peak   | best    | mean    | mode    | worst   | stdev   | rstdev | diff  |
+--------------+-------------+--------+--------+------+-----+------------+---------+---------+---------+---------+---------+--------+-------+
| HashingBench | benchMd5    |        | []     | 1000 | 10  | 1,255,792b | 0.931μs | 0.979μs | 0.957μs | 1.153μs | 0.062μs | 6.37%  | 1.00x |
| HashingBench | benchSha1   |        | []     | 1000 | 10  | 1,255,792b | 0.988μs | 1.015μs | 1.004μs | 1.079μs | 0.026μs | 2.57%  | 1.04x |
+--------------+-------------+--------+--------+------+-----+------------+---------+---------+---------+---------+---------+--------+-------+

```

Testing Combinations
--------------------

[](#testing-combinations)

### When to use Combinations

[](#when-to-use-combinations)

You have a function that takes, for example, three arguments, and you want to test its behaviour with a bunch of different values for each of those arguments.

Copy the below code or use this repo's [example](https://github.com/alexandrajulius/approval-tests/blob/main/tests/Example/GildedRoseCombinationsTest.php)and adjust the number and type of inputs for your use case. Specify the input arguments of the method you want to test in `$arguments`: Either list the values that the arguments can take explicitly in arrays or use `range()`. Then pass those arguments along with an anonymous function into `CombinationApprovals::create()->verifyAllCombinations()`

```
public function testUpdateQualityWithCombinations(): void
{
    $arguments = [
        ['foo', 'bar'], # values for $name
        range(0, 3),    # values for $sellIn
        [15, 20, 25],   # values for $quantity
    ];

    CombinationApprovals::create()->verifyAllCombinations(
        function (string $name, int $sellIn, int $quantity) {
            $items = [new Item($name, $sellIn, $quantity)];

            return (new GildedRose())->updateQuality($items);
        },
        $arguments
    );
}
```

The anonymous function specifies how the input arguments should be passed into the logic that you want to test. Also, it must return the output of your tested logic, so `verifyAllCombinations()` can dump it into the received.txt and compare it to the latest approved.txt.

For the above example, the Approval tool would create all possible combinations of the specified input values, map those to the related output of the tested logic and dump it into the received.txt as such:

```
[bar, 3, 25] -> [bar, 2, 24]
[bar, 3, 20] -> [bar, 2, 19]
[bar, 3, 15] -> [bar, 2, 14]
[bar, 2, 25] -> [bar, 1, 24]
[bar, 2, 20] -> [bar, 1, 19]
[bar, 2, 15] -> [bar, 1, 14]
[bar, 1, 25] -> [bar, 0, 24]
[bar, 1, 20] -> [bar, 0, 19]
[bar, 1, 15] -> [bar, 0, 14]
[bar, 0, 25] -> [bar, -1, 23]
[bar, 0, 20] -> [bar, -1, 18]
[bar, 0, 15] -> [bar, -1, 13]
[foo, 3, 25] -> [foo, 2, 24]
[foo, 3, 20] -> [foo, 2, 19]
[foo, 3, 15] -> [foo, 2, 14]
[foo, 2, 25] -> [foo, 1, 24]
[foo, 2, 20] -> [foo, 1, 19]
[foo, 2, 15] -> [foo, 1, 14]
[foo, 1, 25] -> [foo, 0, 24]
[foo, 1, 20] -> [foo, 0, 19]
[foo, 1, 15] -> [foo, 0, 14]
[foo, 0, 25] -> [foo, -1, 23]
[foo, 0, 20] -> [foo, -1, 18]
[foo, 0, 15] -> [foo, -1, 13]

```

Dependencies
------------

[](#dependencies)

- [PHP 7.4+](http://php.net/downloads.php)
- [phpunit 9+](https://phpunit.de/getting-started/phpunit-9.html)
- [composer](https://getcomposer.org/)

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity30

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/c4d3c5847507f05988f4a0c4d282eecf560c98688890f60815a6ed75da4b684e?d=identicon)[alexandrajulius](/maintainers/alexandrajulius)

---

Top Contributors

[![alexandrajulius](https://avatars.githubusercontent.com/u/23189414?v=4)](https://github.com/alexandrajulius "alexandrajulius (62 commits)")

### Embed Badge

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

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

PHPackages © 2026

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