PHPackages                             skills17/phpunit-helpers - 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. skills17/phpunit-helpers

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

skills17/phpunit-helpers
========================

This package provides some phpunit helpers for usage in a skills competition environment.

v1.3.0(4y ago)0405↓85.7%[3 issues](https://github.com/skills17/phpunit-helpers/issues)MITPHPPHP &gt;=7.4

Since Jan 5Pushed 4y ago11 watchersCompare

[ Source](https://github.com/skills17/phpunit-helpers)[ Packagist](https://packagist.org/packages/skills17/phpunit-helpers)[ RSS](/packages/skills17-phpunit-helpers/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependencies (3)Versions (8)Used By (0)

skills17/phpunit-helpers
========================

[](#skills17phpunit-helpers)

[![](https://camo.githubusercontent.com/952f22d97fa37f90ecf6101dd0d8e59ab6de4aa9cfd05b64ddcf998e7bf0e7f1/68747470733a2f2f637972696c77616e6e65722e6769746875622e696f2f7061636b616765732f736b696c6c7331372f706870756e69742d68656c706572732f6173736574732f6f75747075742d707265766965772e706e67)](https://camo.githubusercontent.com/952f22d97fa37f90ecf6101dd0d8e59ab6de4aa9cfd05b64ddcf998e7bf0e7f1/68747470733a2f2f637972696c77616e6e65722e6769746875622e696f2f7061636b616765732f736b696c6c7331372f706870756e69742d68656c706572732f6173736574732f6f75747075742d707265766965772e706e67)

This package provides some PHPUnit helpers for usage in a skills competition environment. It includes:

- Custom output formatter
- Base test classes
- Automatic database resets
- ... and more

Table of contents
-----------------

[](#table-of-contents)

- [Installation](#installation)
- [Usage](#usage)
    - [Grouping](#grouping)
    - [Non-database tests](#non-database-tests)
    - [Database tests](#database-tests)
    - [Extra tests](#extra-tests)
    - [Output](#output)
    - [`setUp` fixture](#setup-fixture)
- [Best practices](#best-practices)
    - [Time limit](#time-limit)
    - [Writing good tests](#writing-good-tests)
- [License](#license)

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

[](#installation)

**Requirements**:

- PHPUnit `9.0` or greater
- PHP `7.4` or greater

To install this package, simply run the following command:

```
composer require skills17/phpunit-helpers
```

Additionally, create a `phpunit.xml` file in the root folder of your task:

```

            ./tests/

```

To use the provided result printer, the `printerClass` and `printerFile` settings are required. The other ones are suggested settings but can be modified to match your requirements.

It is suggested to add the two additional composer scripts so it is possible to run the tests by executing `composer test` or `composer test:json`.

```
    "scripts": {
        "test": "phpunit --colors=always",
        "test:json": "FORMAT=json phpunit | tail -n +3"
    },
```

Usage
-----

[](#usage)

A `config.json` file needs to be created that contains some information about the task. It should be placed in the root folder of your task, next to the `composer.json` file.

### Grouping

[](#grouping)

A core concept is test groups. You usually don't want to test everything for one criterion in one test function but instead split it into multiple ones for a cleaner test class and a better overview.

In PHP, tests are grouped by a function prefix defined in the `config.json` file.

For example, if you have the criteria that `GET /countries` is implemented correctly and that awards 3 points, you could have the following test functions:

- `testCountriesIndexAll`: test if all available countries get returned
- `testCountriesIndexLimit`: test if an optional limit is respected
- `testCountriesIndexSearch`: test if countries can be searched by an optional query

Now, all these functions have a common prefix: `CountriesIndex` (`test` can be omitted) and the `config.json` will look similar to this:

```
{
  "groups": [
    {
      "match": "CountriesIndex.+"
    }
  ]
}
```

Each one of the test methods will now award 1 point if they pass which results in 3 points in total for the whole group. If you want that *all* three test functions have to pass to get 3 points (and 0 otherwise), you can set the `"required": true` attribute.

### Non-database tests

[](#non-database-tests)

To write a test for an application or a part of it that does not require a database, you can simply extend the `Skills17\PHPUnit\BaseTest` class. It further extends the normal `TestCase` class of PHPUnit so all PHPUnit assert functions are available as well.

### Database tests

[](#database-tests)

If the application under test requires a database, it should get reset before every test run to make sure the data is consistent across multiple test runs. For this case, there are two classes available to extend.

Additionally, a database dump has to be provided and specified in the `config.json` if it does not have the default name.

#### Read tests

[](#read-tests)

If the test and the part of the application that gets tested only *reads* data from the database but never writes/changes it, the `Skills17\PHPUnit\Database\ReadTest` class should get extended.

To improve the performance, this type of test only resets the database once before the test class gets executed.

#### Write tests

[](#write-tests)

If the test or the part of the application that gets tested *writes* data (insert, update, delete), the `Skills17\PHPUnit\Database\WriteTest` class should get extended.

This makes sure that the database gets reset before every test function in the class gets executed, not only once at the beginning of the class like in a read test. It makes sure that each function starts with a fresh database dump, which is especially useful when a previous function failed and so the database is in an unknown state or when only a subset of functions get executed as they have been filtered.

### Extra tests

[](#extra-tests)

To prevent cheating, extra tests can be used. They are not available to the competitors and should test exactly the same things as the normal tests do, but with different values.

For example, if your normal test contains a check to search the list of all countries by 'Sw\*', copy the test into an extra test and change the search string to 'Ca\*'. Since the competitors will not know the extra test, it would detect statically returned values that were returned to simply satisfy the 'Sw\*' tests instead of actually implement the search logic.

Extra tests are detected by their namespace, which should contain `\Extra\`. That means, if your normal test is in the `Skills17\CountriesApp\Test` namespace, the extra test could be in `Skills17\CountriesApp\Test\Extra`. The class- and method names should exactly equal the ones from the normal tests. If they don't, a warning will be displayed.

If an extra test fails while the corresponding normal test passes, a warning will be displayed that a manual review of that test is required since it detected possible cheating. The penalty then has to be decided manually from case to case, the points visible in the output assumed that the test passed and there was no cheating.

For the distribution of the task to the competitors, simply delete the folder containing all extra tests. Nothing else needs to be done or configured.

### Output

[](#output)

When the environment variable `FORMAT` is set to `json`, the result will be printed in json. Otherwise, a well formatted summary will be visible.

### `setUp` fixture

[](#setup-fixture)

If you overwrite the `setUp` fixture in your own test class, make sure to call the parent method.

```
    public function setUp(): void
    {
        parent::setUp();

        // your own code here
    }
```

Best practices
--------------

[](#best-practices)

### Time limit

[](#time-limit)

It is strongly recommended to enforce a time limit on the tests. Otherwise, an endless loop can break the whole testing pipeline.

The following steps show how a time limit can be configured.

1. Install the composer package `phpunit/php-invoker`
2. Add `enforceTimeLimit="true"` to the `phpunit.xml` config file
3. Annotate all tests with eather `@large` (60s timeout), `@medium` (10s timeout) or `@small` (1s timeout)

The timeouts for all test sizes can be [configured](https://phpunit.readthedocs.io/en/9.3/risky-tests.html#risky-tests-test-execution-timeout).

### Writing good tests

[](#writing-good-tests)

For additional advice for writing good tests in a competition environment, read [this blog post](https://skills17.ch/blog/automated-testing-in-a-competition-environment-2020).

License
-------

[](#license)

[MIT](https://github.com/skills17/phpunit-helpers/blob/master/LICENSE)

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 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

Every ~41 days

Recently: every ~51 days

Total

7

Last Release

1709d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/70968320?v=4)[skills17](/maintainers/skills17)[@skills17](https://github.com/skills17)

---

Top Contributors

[![cyrilwanner](https://avatars.githubusercontent.com/u/2709252?v=4)](https://github.com/cyrilwanner "cyrilwanner (43 commits)")

###  Code Quality

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/skills17-phpunit-helpers/health.svg)

```
[![Health](https://phpackages.com/badges/skills17-phpunit-helpers/health.svg)](https://phpackages.com/packages/skills17-phpunit-helpers)
```

###  Alternatives

[orchestra/testbench

Laravel Testing Helper for Packages Development

2.2k39.1M32.1k](/packages/orchestra-testbench)[timacdonald/log-fake

A drop in fake logger for testing with the Laravel framework.

4235.9M56](/packages/timacdonald-log-fake)[jasonmccreary/laravel-test-assertions

A set of helpful assertions when testing Laravel applications.

3513.9M32](/packages/jasonmccreary-laravel-test-assertions)[ergebnis/phpunit-slow-test-detector

Provides facilities for detecting slow tests in phpunit/phpunit.

1468.1M72](/packages/ergebnis-phpunit-slow-test-detector)[typo3/testing-framework

The TYPO3 testing framework provides base classes for unit, functional and acceptance testing.

675.0M775](/packages/typo3-testing-framework)[robiningelbrecht/phpunit-pretty-print

Prettify PHPUnit output

76460.0k15](/packages/robiningelbrecht-phpunit-pretty-print)

PHPackages © 2026

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