This blog will cover how to automate the testing of REST API. Automating the process of testing will ensure that you deliver a robust API. Any changes to the implementation is ensured, not to break any previous API behavior.
In the last blog, we built a REST API using Yii Framework. We will add automated testing of this API using Codeception. Codeception defines itself as
Codeception PHP Testing Framework is designed to work just out of the box. This means its installation requires minimal steps and no external dependencies preinstalled (except PHP, of course)
We will add two packages via composer
php composer.phar require codeception/codeception:~2.0 php composer.phar require flow/jsonpath:~0.2
This will install codcept utility in protected/vendor/bin. We would need flow/jsonpath to verify the JSON returned by the API.
1. Run the following command to setup initial directory structure
./app/protected/vendor/bin/codecept bootstrap
This will create a file codeception.yml and tests directory
2. We will modify codeception.yml, so that it is as follows
actor: Tester paths: tests: tests log: tests/_output data: tests/_data helpers: tests/_support settings: bootstrap: _bootstrap.php colors: true memory_limit: 1024M modules: config: Db: dsn: 'mysql:host=localhost;dbname=televod' user: 'test_televod' password: 'test_televod'
The important points to note are:
All the automated testing code is in tests directory, separate from application code, which is in app directory
Db module will help us configure data in the database, before the test and verify that database has been properly updated after the API is called.
Codeception documentation of setting up for web-services is given here
1- We create a new test suite for API with the following command
./app/protected/vendor/bin/codecept generate:suite api
This will create api.suite.yml file and api directory.
2- We will change the content of api.suite.yml as follows
class_name: ApiTester modules: enabled: [PhpBrowser, REST, ApiHelper, Db] config: PhpBrowser: url: http://192.168.1.77/ REST: url: http://192.168.1.77/api/
3- Then we add a test for getting series listing API.
./app/protected/vendor/bin/codecept generate:cept api GetSeriesList
This will add a GetSeriesListCept.php in the api directory
4- We will then build the tests, using the following command
./app/protected/vendor/bin/codecept build
Edit GetSeriesListCept.php with the following test
$I = new ApiTester($scenario); $I->wantTo('get an empty list'); $I->sendGET('series'); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); $I->seeResponseContainsJson(["success" => false]); $I->seeResponseContainsJson(["message" => "No Record(s) Found"]); $seriesList = $I->grabDataFromResponseByJsonPath("$.data.series.*"); \PHPUnit_Framework_Assert::assertEmpty($seriesList);
We can run the tests in api suite by the following command
./app/protected/vendor/bin/codecept run api
It should print something like
Api Tests (1) ------------ Get an empty list (GetSeriesListCept) Ok --------------------------
1- We will add a new test
./app/protected/vendor/bin/codecept generate:cept api GetSeriesList2
2- We add the following test
$I = new ApiTester($scenario); $I->wantTo('get a single item in list'); $I->haveInDatabase('tbl_series', array('id' => 1, 'title' => 'series 1', 'updated' => '')); $I->sendGET('series'); $I->seeResponseCodeIs(200); $I->seeResponseIsJson(); $I->seeResponseContainsJson(["success" => true]); $seriesList = $I->grabDataFromResponseByJsonPath("$.data.series.*"); \PHPUnit_Framework_Assert::assertEquals(1, count($seriesList)); $series1 = $seriesList[0]; \PHPUnit_Framework_Assert::assertEquals($series1['id'], 1);
We can run the tests again and see the response
Api Tests (2) -------------- Get a single item in list (GetSeriesList2Cept) Ok Get an empty list (GetSeriesListCept) Ok ----------------------------
Details of asserts available in PHP-Unit are listed here
JSON expression can be tested using this tool