Back to Blog Back to Career

Automated Testing Of A RESTful API

Categories : ,
Author : vadion
Date : 17-05-2015
No Comments


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)

Installing Codeception

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.

Configuring Codeception

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.

Adding Test Suite

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

Writing Tests

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);

Running Tests

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
--------------------------

Writing Test with DB interaction

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
----------------------------

Resources

Details of asserts available in PHP-Unit are listed here
JSON expression can be tested using this tool