{"id":13616403,"url":"https://github.com/jolicode/asynit","last_synced_at":"2025-04-06T04:14:54.099Z","repository":{"id":44413303,"uuid":"73373882","full_name":"jolicode/asynit","owner":"jolicode","description":":stars: Asynchronous HTTP Request Testing Library for API or more...","archived":false,"fork":false,"pushed_at":"2024-04-12T09:00:02.000Z","size":209,"stargazers_count":76,"open_issues_count":1,"forks_count":9,"subscribers_count":19,"default_branch":"master","last_synced_at":"2024-04-14T14:53:09.938Z","etag":null,"topics":["amphp","http","phpunit"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jolicode.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2016-11-10T11:01:55.000Z","updated_at":"2024-04-19T09:32:22.140Z","dependencies_parsed_at":"2024-03-15T13:54:20.194Z","dependency_job_id":"5f173e5b-7e59-43f3-9a58-990d148fafbe","html_url":"https://github.com/jolicode/asynit","commit_stats":{"total_commits":108,"total_committers":13,"mean_commits":8.307692307692308,"dds":0.4907407407407407,"last_synced_commit":"98437c71ebf70a17d8a2df133a5c7fce26fb5396"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jolicode%2Fasynit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jolicode%2Fasynit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jolicode%2Fasynit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jolicode%2Fasynit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jolicode","download_url":"https://codeload.github.com/jolicode/asynit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247430963,"owners_count":20937875,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amphp","http","phpunit"],"created_at":"2024-08-01T20:01:28.072Z","updated_at":"2025-04-06T04:14:54.084Z","avatar_url":"https://github.com/jolicode.png","language":"PHP","readme":"# asynit\n\nAsynchronous (if library use fiber) testing library runner for HTTP / API and more...\n\n## Install\n\n```\ncomposer require --dev jolicode/asynit\n```\n\n## Usage\n\n### Writing a test\n\nAsynit will read PHP's classes to find available Test using the `Asynit\\Attribute\\TestCase` attribute. You need to\ncreate a test class in some directory, which will have the `TestCase` attribute of\nAsynit:\n\n```php\nuse Asynit\\Attribute\\TestCase;\n\n#[TestCase]\nclass ApiTest\n{\n}\n```\n\nThen you can add some tests that will use the API of the TestCase class:\n\n```php\nuse Asynit\\Attribute\\Test;\nuse Asynit\\Attribute\\TestCase;\n\n#[TestCase]\nclass ApiTest\n{\n    #[Test]\n    public function my_test()\n    {\n        // do some test\n    }\n}\n```\n\nNote: All test methods should be prefixed by the `test` keyword or use the `Asynit\\Attribute\\Test` anotation. All others\nmethods will not be executed automatically.\n\nA test fail when an exception occurs during the test\n\n### Using assertion\n\nAsynit provide trait to ease the writing of test. You can use the `Asynit\\AssertCaseTrait` trait to use the assertion.\n\n```php\nuse Asynit\\Attribute\\Test;\nuse Asynit\\Attribute\\TestCase;\n\n#[TestCase]\nclass ApiTest\n{\n    use Asynit\\AssertCaseTrait;\n\n    #[Test]\n    public function my_test()\n    {\n        $this-\u003eassertSame('foo', 'foo');\n    }\n}\n```\n\nAll assertions supported by PHPUnit are also supported by Asynit thanks to the\n[bovigo-assert](https://github.com/mikey179/bovigo-assert) library.\nBut you can use your own as long as it's throw an exception on failure.\n\n### Running the test\n\nFor running this test you will only need to use the PHP file provided by this\nproject:\n\n```bash\n$ php vendor/bin/asynit path/to/the/file.php\n```\n\nIf you have many test files, you can run Asynit with a directory\n\n```bash\n$ php vendor/bin/asynit path/to/the/directory\n```\n\n### Using HTTP Client\n\nAsynit provide an optional `Asynit\\HttpClient\\HttpClientWebCaseTrait` trait that you can use to make HTTP request. You will need to install `amphp/http-client` and\n`nyholm/psr7` to use it.\n\n```php\nuse Asynit\\Attribute\\TestCase;\nuse Asynit\\HttpClient\\HttpClientWebCaseTrait;\n\n#[TestCase]\nclass FunctionalHttpTests\n{\n    use HttpClientWebCaseTrait;\n\n    public function testGet()\n    {\n        $response = $this-\u003eget('https//example.com');\n\n        $this-\u003eassertStatusCode(200, $response);\n    }\n}\n```\n\nYou can also use a more oriented API trait `Asynit\\HttpClient\\HttpClientApiCaseTrait` that will allow you to write test like this:\n\n\n\n```php\nuse Asynit\\Attribute\\TestCase;\nuse Asynit\\HttpClient\\HttpClientApiCaseTrait;\n\n#[TestCase]\nclass FunctionalHttpTests\n{\n    use HttpClientApiCaseTrait;\n\n    public function testGet()\n    {\n        $response = $this-\u003eget('https//example.com');\n\n        $this-\u003eassertStatusCode(200, $response);\n        $this-\u003eassertSame('bar', $response['foo']);\n    }\n}\n```\n\n### Dependency between tests\n\nSometime a test may need a value from the result of another test, like an\nauthentication token that need to be available for some requests (or a cookie\ndefining the session).\n\nAsynit provides a `Depend` attribute which allows you to specify that a test is\ndependent from another one.\n\nSo if you have 3 tests, `A`, `B` and `C` and you say that `C` depend on `A`;\nTest `A` and `B` will be run in parallel and once `A` is completed and\nsuccessful, `C` will be run with the result from `A`.\n\nLet's see an example:\n\n```php\nuse Asynit\\Attribute\\Depend;\nuse Asynit\\Attribute\\TestCase;\nuse Asynit\\HttpClient\\HttpClientApiCaseTrait;\n\n#[TestCase]\nclass SecurityTest extends TestCase\n{\n    use HttpClientApiCaseTrait;\n\n    public function testLogin()\n    {\n        $response = $this-\u003epost('/', ['username' =\u003e user, 'password' =\u003e 'test']);\n\n        $this-\u003eassertStatusCode(200, $response);\n\n        return $response-\u003egetBody()-\u003egetContents();\n    }\n\n    #[Depend(\"testLogin\")]\n    public function testAuthenticatedRequest(string $token)\n    {\n        $response = $this-\u003eget('/api', headers: ['X-Auth-Token' =\u003e $token]);\n\n        $this-\u003eassertStatusCode(200, $response);\n    }\n}\n```\n\nHere `testAuthenticatedRequest` will only be run after `testLogin` has been\ncompleted. You can also use dependency between different test case. The previous\ntest case is under the `Application\\ApiTest` namespace and thus we can write\nanother test case like this:\n\n```php\nuse Asynit\\Attribute\\Depend;\nuse Asynit\\Attribute\\TestCase;\nuse Asynit\\HttpClient\\HttpClientApiCaseTrait;\n\n#[TestCase]\nclass PostTest\n{\n    #[Depend(\"Application\\ApiTest\\SecurityTest::testLogin\")]\n    public function testGet($token)\n    {\n        $response = $this-\u003eget('/posts', headers: ['X-Auth-Token' =\u003e $token]);\n\n        $this-\u003eassertStatusCode(200, $response);\n    }\n}\n```\n\n### Test Organization\n\nIt's really common to reuse this token in a lot of test, and maybe you don't need test when fetching the token.\nAsynit allow you to depend on any method of any class.\n\nSo you could write a `TokenFetcherClass` that will fetch the token and then use it in your test.\n\n```php\nnamespace App\\Tests;\n\nuse Asynit\\HttpClient\\HttpClientApiCaseTrait;\n\nclass TokenFetcher\n{\n    use HttpClientApiCaseTrait;\n\n    protected function fetchToken(string $email, string $password = 'password')\n    {\n        $payload = [\n            'email' =\u003e $email,\n            'password' =\u003e $password,\n        ];\n\n        $response = $this-\u003epost('/users/token', ['username' =\u003e 'user', 'password' =\u003e 'test']);\n\n        return $response['token'];\n    }\n    \n    protected function fetchUserToken()\n    {\n        return $this-\u003efetchToken('email@example.com', 'password');\n    }\n}\n```\n\nThen in your test class you will be able to call this method:\n\n```php\nnamespace App\\Tests;\n\nuse Asynit\\Attribute\\Depend;\nuse Asynit\\Attribute\\TestCase;\nuse Asynit\\HttpClient\\HttpClientApiCaseTrait;\n\n#[TestCase]\nclass OrganizationTest\n{\n    use HttpClientApiCaseTrait;\n\n    #[Depend(\"App\\Tests\\TokenFetcher::fetchUserToken\")]\n    public function test_api_method_with_token(string $token)\n    {\n        $response = $this-\u003eget('/api', headers: ['X-Auth-Token' =\u003e $token]);\n\n        // ...\n    }\n}\n```\n\nAs you may notice, the `fetchUserToken` method does not start with `test`. Thus\nby default this method will not be included in the test suite. But as it is a\ndependency of a test, it will be included as a regular test in the global test\nsuite and will leverage the cache system.\n\n","funding_links":[],"categories":["Testing","PHP"],"sub_categories":["Tunnel"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjolicode%2Fasynit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjolicode%2Fasynit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjolicode%2Fasynit/lists"}