PHPackages                             jolicode/asynit - 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. jolicode/asynit

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

jolicode/asynit
===============

Asynchronous HTTP Request Testing Library for API or more...

v0.17.0(7mo ago)81551.0k↓55.2%7[1 issues](https://github.com/jolicode/asynit/issues)MITPHPPHP ^8.2CI passing

Since Jun 23Pushed 3mo ago17 watchersCompare

[ Source](https://github.com/jolicode/asynit)[ Packagist](https://packagist.org/packages/jolicode/asynit)[ RSS](/packages/jolicode-asynit/feed)WikiDiscussions master Synced 2w ago

READMEChangelog (10)Dependencies (6)Versions (32)Used By (0)

asynit
======

[](#asynit)

Asynchronous (if library use fiber) testing library runner for HTTP / API and more...

Install
-------

[](#install)

```
composer require --dev jolicode/asynit

```

Usage
-----

[](#usage)

### Writing a test

[](#writing-a-test)

Asynit will read PHP's classes to find available Test using the `Asynit\Attribute\TestCase` attribute. You need to create a test class in some directory, which will have the `TestCase` attribute of Asynit:

```
use Asynit\Attribute\TestCase;

#[TestCase]
class ApiTest
{
}
```

Then you can add some tests that will use the API of the TestCase class:

```
use Asynit\Attribute\Test;
use Asynit\Attribute\TestCase;

#[TestCase]
class ApiTest
{
    #[Test]
    public function my_test()
    {
        // do some test
    }
}
```

Note: All test methods should be prefixed by the `test` keyword or use the `Asynit\Attribute\Test` anotation. All others methods will not be executed automatically.

A test fail when an exception occurs during the test

### Using assertion

[](#using-assertion)

Asynit provide trait to ease the writing of test. You can use the `Asynit\AssertCaseTrait` trait to use the assertion.

```
use Asynit\Attribute\Test;
use Asynit\Attribute\TestCase;

#[TestCase]
class ApiTest
{
    use Asynit\AssertCaseTrait;

    #[Test]
    public function my_test()
    {
        $this->assertSame('foo', 'foo');
    }
}
```

All assertions supported by PHPUnit are also supported by Asynit thanks to the [bovigo-assert](https://github.com/mikey179/bovigo-assert) library. But you can use your own as long as it's throw an exception on failure.

### Running the test

[](#running-the-test)

For running this test you will only need to use the PHP file provided by this project:

```
$ php vendor/bin/asynit path/to/the/file.php
```

If you have many test files, you can run Asynit with a directory

```
$ php vendor/bin/asynit path/to/the/directory
```

### Using HTTP Client

[](#using-http-client)

Asynit provide an optional `Asynit\HttpClient\HttpClientWebCaseTrait` trait that you can use to make HTTP request. You will need to install `amphp/http-client` and `nyholm/psr7` to use it.

```
use Asynit\Attribute\TestCase;
use Asynit\HttpClient\HttpClientWebCaseTrait;

#[TestCase]
class FunctionalHttpTests
{
    use HttpClientWebCaseTrait;

    public function testGet()
    {
        $response = $this->get('https//example.com');

        $this->assertStatusCode(200, $response);
    }
}
```

You can also use a more oriented API trait `Asynit\HttpClient\HttpClientApiCaseTrait` that will allow you to write test like this:

```
use Asynit\Attribute\TestCase;
use Asynit\HttpClient\HttpClientApiCaseTrait;

#[TestCase]
class FunctionalHttpTests
{
    use HttpClientApiCaseTrait;

    public function testGet()
    {
        $response = $this->get('https//example.com');

        $this->assertStatusCode(200, $response);
        $this->assertSame('bar', $response['foo']);
    }
}
```

### Dependency between tests

[](#dependency-between-tests)

Sometime a test may need a value from the result of another test, like an authentication token that need to be available for some requests (or a cookie defining the session).

Asynit provides a `Depend` attribute which allows you to specify that a test is dependent from another one.

So if you have 3 tests, `A`, `B` and `C` and you say that `C` depend on `A`; Test `A` and `B` will be run in parallel and once `A` is completed and successful, `C` will be run with the result from `A`.

Let's see an example:

```
use Asynit\Attribute\Depend;
use Asynit\Attribute\TestCase;
use Asynit\HttpClient\HttpClientApiCaseTrait;

#[TestCase]
class SecurityTest extends TestCase
{
    use HttpClientApiCaseTrait;

    public function testLogin()
    {
        $response = $this->post('/', ['username' => user, 'password' => 'test']);

        $this->assertStatusCode(200, $response);

        return $response->getBody()->getContents();
    }

    #[Depend("testLogin")]
    public function testAuthenticatedRequest(string $token)
    {
        $response = $this->get('/api', headers: ['X-Auth-Token' => $token]);

        $this->assertStatusCode(200, $response);
    }
}
```

Here `testAuthenticatedRequest` will only be run after `testLogin` has been completed. You can also use dependency between different test case. The previous test case is under the `Application\ApiTest` namespace and thus we can write another test case like this:

```
use Asynit\Attribute\Depend;
use Asynit\Attribute\TestCase;
use Asynit\HttpClient\HttpClientApiCaseTrait;

#[TestCase]
class PostTest
{
    #[Depend("Application\ApiTest\SecurityTest::testLogin")]
    public function testGet($token)
    {
        $response = $this->get('/posts', headers: ['X-Auth-Token' => $token]);

        $this->assertStatusCode(200, $response);
    }
}
```

### Test Organization

[](#test-organization)

It's really common to reuse this token in a lot of test, and maybe you don't need test when fetching the token. Asynit allow you to depend on any method of any class.

So you could write a `TokenFetcherClass` that will fetch the token and then use it in your test.

```
namespace App\Tests;

use Asynit\HttpClient\HttpClientApiCaseTrait;

class TokenFetcher
{
    use HttpClientApiCaseTrait;

    protected function fetchToken(string $email, string $password = 'password')
    {
        $payload = [
            'email' => $email,
            'password' => $password,
        ];

        $response = $this->post('/users/token', ['username' => 'user', 'password' => 'test']);

        return $response['token'];
    }

    protected function fetchUserToken()
    {
        return $this->fetchToken('email@example.com', 'password');
    }
}
```

Then in your test class you will be able to call this method:

```
namespace App\Tests;

use Asynit\Attribute\Depend;
use Asynit\Attribute\TestCase;
use Asynit\HttpClient\HttpClientApiCaseTrait;

#[TestCase]
class OrganizationTest
{
    use HttpClientApiCaseTrait;

    #[Depend("App\Tests\TokenFetcher::fetchUserToken")]
    public function test_api_method_with_token(string $token)
    {
        $response = $this->get('/api', headers: ['X-Auth-Token' => $token]);

        // ...
    }
}
```

As you may notice, the `fetchUserToken` method does not start with `test`. Thus by default this method will not be included in the test suite. But as it is a dependency of a test, it will be included as a regular test in the global test suite and will leverage the cache system.

###  Health Score

59

—

FairBetter than 98% of packages

Maintenance73

Regular maintenance activity

Popularity46

Moderate usage in the ecosystem

Community23

Small or concentrated contributor base

Maturity77

Established project with proven stability

 Bus Factor1

Top contributor holds 58.3% 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 ~115 days

Recently: every ~160 days

Total

28

Last Release

214d ago

PHP version history (5 changes)v0.2.0PHP ^7.0

v0.7.0PHP ^7.2

v0.8.0PHP ^7.3 || ^8.0

v0.12.0PHP ^8.1

v0.13.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/16ce838e2759f19597de56865243a88711d822ba923c61e024090e87e4d3fc5f?d=identicon)[joelwurtz](/maintainers/joelwurtz)

---

Top Contributors

[![joelwurtz](https://avatars.githubusercontent.com/u/90466?v=4)](https://github.com/joelwurtz "joelwurtz (120 commits)")[![lyrixx](https://avatars.githubusercontent.com/u/408368?v=4)](https://github.com/lyrixx "lyrixx (52 commits)")[![Korbeil](https://avatars.githubusercontent.com/u/944409?v=4)](https://github.com/Korbeil "Korbeil (10 commits)")[![pyrech](https://avatars.githubusercontent.com/u/2021641?v=4)](https://github.com/pyrech "pyrech (8 commits)")[![welcoMattic](https://avatars.githubusercontent.com/u/773875?v=4)](https://github.com/welcoMattic "welcoMattic (6 commits)")[![xavierlacot](https://avatars.githubusercontent.com/u/177293?v=4)](https://github.com/xavierlacot "xavierlacot (2 commits)")[![mykiwi](https://avatars.githubusercontent.com/u/334432?v=4)](https://github.com/mykiwi "mykiwi (2 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (2 commits)")[![samnela](https://avatars.githubusercontent.com/u/1852108?v=4)](https://github.com/samnela "samnela (1 commits)")[![tlenclos](https://avatars.githubusercontent.com/u/686101?v=4)](https://github.com/tlenclos "tlenclos (1 commits)")[![pborreli](https://avatars.githubusercontent.com/u/77759?v=4)](https://github.com/pborreli "pborreli (1 commits)")[![damienalexandre](https://avatars.githubusercontent.com/u/225704?v=4)](https://github.com/damienalexandre "damienalexandre (1 commits)")

---

Tags

amphphttpphpunit

### Embed Badge

![Health badge](/badges/jolicode-asynit/health.svg)

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

###  Alternatives

[phpro/grumphp

A composer plugin that enables source code quality checks.

4.3k17.0M1.1k](/packages/phpro-grumphp)[laravel/framework

The Laravel Framework.

34.9k556.2M21.5k](/packages/laravel-framework)[infection/infection

Infection is a Mutation Testing framework for PHP. The mutation adequacy score can be used to measure the effectiveness of a test set in terms of its ability to detect faults.

2.2k30.0M2.8k](/packages/infection-infection)[phparkitect/phparkitect

Enforce architectural constraints in your PHP applications

9244.5M32](/packages/phparkitect-phparkitect)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

103574.3k69](/packages/friendsoftypo3-content-blocks)[testo/testo

A lightweight PHP testing framework.

20319.6k179](/packages/testo-testo)

PHPackages © 2026

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