{"id":15014431,"url":"https://github.com/lchrusciel/apitestcase","last_synced_at":"2025-05-15T08:05:22.844Z","repository":{"id":45310192,"uuid":"45345838","full_name":"lchrusciel/ApiTestCase","owner":"lchrusciel","description":"Handy PHPUnit test case for testing JSON APIs in your Symfony applications.","archived":false,"fork":false,"pushed_at":"2024-07-29T13:13:04.000Z","size":389,"stargazers_count":409,"open_issues_count":11,"forks_count":37,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-06T20:07:28.399Z","etag":null,"topics":["api","hacktoberfest","php","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/lchrusciel.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,"publiccode":null,"codemeta":null}},"created_at":"2015-11-01T15:30:08.000Z","updated_at":"2025-03-19T19:05:19.000Z","dependencies_parsed_at":"2023-10-14T21:15:16.934Z","dependency_job_id":"1035a0b3-8d52-4052-b2e9-0f4e707874b0","html_url":"https://github.com/lchrusciel/ApiTestCase","commit_stats":{"total_commits":222,"total_committers":26,"mean_commits":8.538461538461538,"dds":0.5135135135135135,"last_synced_commit":"420bfe7cc433ef2f24a058050e196afe2dd02bcd"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lchrusciel%2FApiTestCase","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lchrusciel%2FApiTestCase/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lchrusciel%2FApiTestCase/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lchrusciel%2FApiTestCase/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lchrusciel","download_url":"https://codeload.github.com/lchrusciel/ApiTestCase/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248423522,"owners_count":21100999,"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":["api","hacktoberfest","php","phpunit"],"created_at":"2024-09-24T19:45:37.638Z","updated_at":"2025-04-11T14:49:25.700Z","avatar_url":"https://github.com/lchrusciel.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"ApiTestCase\n===========\n\n![Build](https://github.com/lchrusciel/ApiTestCase/workflows/Build/badge.svg)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/lchrusciel/ApiTestCase/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/lchrusciel/ApiTestCase/?branch=master)\n\n**ApiTestCase** is a PHPUnit TestCase that will make your life as a Symfony API developer much easier. It extends basic [Symfony](https://symfony.com/) WebTestCase with some cool features. \n\nThanks to [PHP-Matcher](https://github.com/coduo/php-matcher) you can, according to its readme, \"write expected json responses like a gangster\". We definitely agree.\n\nIt also uses [Alice](https://github.com/nelmio/alice) for easy Doctrine fixtures loading.\n\nFeatures:\n\n* Clear TDD workflow for API development with Symfony;\n* JSON/XML matching with clear error messages;\n* Fixtures loading with Alice *(optional)*;\n\nInstallation\n------------\n\nAssuming you already have Composer installed globally:\n\n```bash\ncomposer require --dev lchrusciel/api-test-case\n```\n\nAnd it's done! ApiTestCase is working with the default configuration.\n \nUsage\n-----\n\nWe provide two base classes for your test cases: JsonApiTestCase and the XmlApiTestCase. Choose one based on the format of the API you want to create.\n\n### Json Example\n\nThe basic TDD workflow is the following:\n\n1. Write a test case that sends the request and use ``assertResponse`` assertion method to check if response contents are matching your expectations. You need a name for the response file;\n2. Create the file with name that you picked in step 1. and put expected response contents there. It should be put in ``src/AppBundle/Tests/Responses/Expected/hello_world.json`` for example.\n3. Make it red.\n4. Make it green.\n5. Refactor.\n\nLet's see a simple example! Write the following test:\n\n```php\n\nnamespace AppBundle\\Tests\\Controller\\HelloWorldTest;\n\nuse ApiTestCase\\JsonApiTestCase;\n\nclass HelloWorldTest extends JsonApiTestCase\n{\n    public function testGetHelloWorldResponse()\n    {\n        $this-\u003eclient-\u003erequest('GET', '/');\n\n        $response = $this-\u003eclient-\u003egetResponse();\n\n        $this-\u003eassertResponse($response, 'hello_world');\n    }\n}\n```\n\nNow define the expected response file:\n\n```json\n{\n    \"message\": \"Hello ApiTestCase World!\"\n}\n```\n\nRun your tests:\n\n```bash\nvendor/bin/phpunit\n```\n\nYour test should fail with some errors, you are probably missing the controller and routing, so go ahead and define them!\nAs soon as you implement your Controller and configure appropriate routing, you can run your tests again:\n\nIf the response contents will match our expectations, console will present a simple message:\n\n```bash\nOK (1 tests, 2 assertions)\n```\n\nOtherwise it will present diff of received messages:\n\n```bash\n\"Hello ApiTestCase World\" does not match \"Hello ApiTestCase World!\".\n@@ -1,4 +1,3 @@\n {\n-    \"message\": \"Hello ApiTestCase World!\"\n+    \"message\": \"Hello ApiTestCase World\"\n }\n-\n```\n\nFirstly, function `assertResponse` will check the response code (200 is a default response code), then it will check if header of response contains `application/json` content type. At the end it will check if the response contents matches the expectation. \nSometimes you can't predict some values in the response, for example autogenerated date or id from the database. No magic is needed here because [PHP-Matcher](https://github.com/coduo/php-matcher) comes with a helping hand. These are just a few examples of available patterns:\n\n* ``@string@``\n* ``@integer@``\n* ``@boolean@``\n* ``@array@``\n\nCheck for more on [PHP-Matcher's documentation](https://github.com/coduo/php-matcher). \n\nWith these patterns your expected response will look like this:\n\n```json\n{\n    \"message\": \"@string@\"\n}\n```\n\nWith this in place, any string under key `message` will match the pattern. More complicated expected response could look like this:\n\n```json\n[\n    {\n        \"id\": \"@integer@\",\n        \"name\": \"Star-Wars T-shirt\",\n        \"sku\": \"SWTS\",\n        \"price\": 5500,\n        \"sizes\": \"@array@\",\n        \"created_at\": \"@string@.isDateTime()\"\n    },\n    {\n        \"id\": \"@integer@\",\n        \"name\": \"Han Solo Mug\",\n        \"sku\": \"HSM\",\n        \"price\": 500,\n        \"sizes\": \"@array@\",\n        \"created_at\": \"@string@.isDateTime()\"\n    }\n]\n```\n\nAnd will match the following list of products:\n\n```php\narray(\n    array(\n        'id' =\u003e 1,\n        'name' =\u003e 'Star-Wars T-shirt',\n        'sku' =\u003e 'SWTS',\n        'price' =\u003e 5500,\n        'sizes' =\u003e array('S', 'M', 'L'),\n        'created_at' =\u003e new \\DateTime(),\n    ),\n    array(\n        'id' =\u003e 2,\n        'name' =\u003e 'Han Solo Mug',\n        'sku' =\u003e 'HSM',\n        'price' =\u003e 500,\n        'sizes' =\u003e array('S', 'L'),\n        'created_at' =\u003e new \\DateTime(),\n    ),\n)\n```\n\n### Testing With Database Fixtures\n\nApiTestCase is integrated with ``nelmio/alice``. Thanks to this nice library you can easily load your fixtures when you need them. You have to define your fixtures and place them in an appropriate directory.\nHere is some example how to define your fixtures and use case. For more information how to define your fixtures check [Alice's documentation](https://github.com/nelmio/alice). \n\nIn order to use Alice with Doctrine, you should enable two additional bundles:\n\n**Symfony 4.0+**\n\n```php\n// config/bundles.php\nreturn [\n    // ...\n    \n    Nelmio\\Alice\\Bridge\\Symfony\\NelmioAliceBundle::class =\u003e ['test' =\u003e true],\n    Fidry\\AliceDataFixtures\\Bridge\\Symfony\\FidryAliceDataFixturesBundle::class =\u003e ['test' =\u003e true],\n];\n```\n\nNow, let's say you have a mapped Doctrine entity called Book in your application: \n\n```php\n    class Book \n    {\n        private $id;\n        private $title;\n        private $author;\n    \n        // ... \n    }\n```\n\nTo load fixtures for the test, you need to define a simple ``YAML`` file in ``src/AppBundle/Tests/DataFixtures/ORM/books.yml``:\n\n```yml\n    ApiTestCase\\Test\\Entity\\Book:\n        book1:\n            title: \"Lord of The Rings\"\n            author: \"J. R. R. Tolkien\"\n        book2:\n            title: \"Game of Thrones\"\n            price: \"George R. R. Martin\"\n```\n\nFinally, to use these fixtures in a test, just call a proper method:\n\n```php\n    public function testBooksIndexAction()\n    {\n        // This method require subpath to locate specific fixture file in your DataFixtures/ORM directory.\n        $this-\u003eloadFixturesFromFile('books.yml');  \n      \n        // There is another method that allows you to load fixtures from directory.\n        $this-\u003eloadFixturesFromDirectory('big_library');\n    }\n```\n\nConfiguration Reference\n-----------------------\n\nTo customize your test suite configuration you can add a few more options to phpunit.xml:\n\n```xml\n\u003cphp\u003e\n    \u003cserver name=\"KERNEL_CLASS\" value=\"Acme\\Kernel\" /\u003e\n    \u003cserver name=\"EXPECTED_RESPONSE_DIR\" value=\"/path/to/expected/responses/\" /\u003e\n    \u003cserver name=\"FIXTURES_DIR\" value=\"/path/to/DataFixtures/ORM/\" /\u003e\n    \u003cserver name=\"OPEN_ERROR_IN_BROWSER\" value=\"true/false\" /\u003e\n    \u003cserver name=\"OPEN_BROWSER_COMMAND\" value=\"open %s\" /\u003e\n    \u003cserver name=\"IS_DOCTRINE_ORM_SUPPORTED\" value=\"true/false\" /\u003e\n    \u003cserver name=\"TMP_DIR\" value=\"/tmp/path/to/temporary/folder/\" /\u003e\n    \u003cserver name=\"ESCAPE_JSON\" value=\"true/false\" /\u003e\n\u003c/php\u003e\n```\n\n * `KERNEL_CLASS` allows you to specify exactly which class should be used in order to setup the Kernel. \n * `ERESPONSE_DIR` variable contain paths to folder with expected responses. It is used when API result is compared with existing json file. If this value isn't set, ApiTestCase will try to guess location of responses, looking for the responses in a folder: '../Responses' relatively located to your controller test class.\n * `FIXTURES_DIR` variable contains a path to folder with your data fixtures. By default if this variable isn't set it will search for `../DataFixtures/ORM/` relatively located to your test class . ApiTestCase throws RunTimeException if folder doesn't exist or there won't be any files to load.\n * `OPEN_ERROR_IN_BROWSER` is a flag which turns on displaying error in a browser window. The default value is false.\n * `OPEN_BROWSER_COMMAND` is a command which will be used to open browser with an exception.\n * `IS_DOCTRINE_ORM_SUPPORTED` is a flag which turns on doctrine support includes handy data fixtures loader and database purger.\n * `TMP_DIR` variable contains a path to temporary folder, where the log files will be stored.\n * `ESCAPE_JSON` is a flag which turns on escaping (unicode characters and slashes) of your JSON output before comparing it to expected data. The default value is false. This flag only exists for backwards compatibility with previous versions of ApiTestCase (when turned on) and will be removed in a future version.\n \nSample Project\n--------------\n\nIn the ``test/`` directory, you can find sample Symfony project with minimal configuration required to use this library.\n\n### Testing\n\nIn order to run our PHPUnit tests suite, execute following commands:\n\n```bash\ncomposer install\ntest/app/console doctrine:database:create\ntest/app/console doctrine:schema:create\nvendor/bin/phpunit\n```\n\nBug Tracking and Suggestions\n----------------------------\n\nIf you have found a bug or have a great idea for improvement, please [open an issue on this repository](https://github.com/lchrusciel/ApiTestCase/issues/new).\n\nVersioning\n----------\n\nReleases will be numbered with the format `major.minor.patch`.\n\nAnd constructed with the following guidelines.\n\n* Breaking backwards compatibility bumps the major.\n* New additions without breaking backwards compatibility bumps the minor.\n* Bug fixes and misc changes bump the patch.\n\nFor more information on SemVer, please visit [semver.org website](http://semver.org/).\n\nMIT License\n-----------\n\nLicense can be found [here](https://github.com/lchrusciel/ApiTestCase/blob/master/LICENSE).\n\nAuthors\n-------\n\nThe library was originally created by:\n\n* [Łukasz Chruściel](https://github.com/lchrusciel) \n* [Michał Marcinkowski](https://github.com/michalmarcinkowski)\n* [Paweł Jędrzejewski](https://github.com/pjedrzejewski)\n* [Arkadiusz Krakowiak](https://github.com/Arminek)\n\nat [Lakion](http://github.com/Lakion/) company under [https://github.com/Lakion/ApiTestCase](https://github.com/Lakion/ApiTestCase) repository.\n\nSee the list of [contributors](https://github.com/lchrusciel/ApiTestCase/graphs/contributors).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flchrusciel%2Fapitestcase","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flchrusciel%2Fapitestcase","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flchrusciel%2Fapitestcase/lists"}