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(5mo ago)81550.8k↓53.3%7[1 issues](https://github.com/jolicode/asynit/issues)MITPHPPHP ^8.2CI passing

Since Jun 23Pushed 1mo ago17 watchersCompare

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

READMEChangelog (10)Dependencies (6)Versions (30)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

60

—

FairBetter than 98% of packages

Maintenance80

Actively maintained with recent releases

Popularity47

Moderate usage in the ecosystem

Community23

Small or concentrated contributor base

Maturity76

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

169d 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.3k16.7M1.0k](/packages/phpro-grumphp)[laravel/framework

The Laravel Framework.

34.8k543.8M20.1k](/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.2k28.9M2.4k](/packages/infection-infection)[phparkitect/phparkitect

Enforce architectural constraints in your PHP applications

9224.3M28](/packages/phparkitect-phparkitect)[friendsoftypo3/content-blocks

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

103519.9k53](/packages/friendsoftypo3-content-blocks)[testo/testo

A lightweight PHP testing framework.

1959.3k55](/packages/testo-testo)

PHPackages © 2026

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