Backend Coder Logo

PHP Unit Testing with Karma and Jasmine

Published: 19th Oct 2016

This is legacy material. Now I recommend PHP testing using my Easy Testing of PHP system.

test spec

  • Unit test your PHP code modules in the same way that you do for your Javascript code
  • Test Javascript and PHP code at the same time using Karma under NodeJS
  • Easily identify fatal errors, warnings, and parse errors in your PHP code
  • Easy test spec authoring using methods that mimic Jasmine nested Describe and It constructions
  • Write neat code-folding-friendly test specs using your usual editor such as Sublime Text
  • Run all of your tests in one familiar environment

Download PHP Tester from GitHub.

Install using Node Package Manager PHP Tester on NPM

Resources

Running PHP Scripts from Javascript

We may output Javascript code from a PHP script by simply printing valid code syntax to the output buffer.

The script will be accessed by it's URL on a server that is running PHP. We may add this URL to the Karma configuration file in the list of files to load in the browser.

If there are any errors or warnings due to bugs in the PHP code, we will see an unhelpful script error message in the test runner output. So we want to trap these errors and wrap them in a test that displays the error in the test runner output.

Even if our initial tests pass, modifications to PHP modules that are being tested later may well cause PHP errors. So we must trap these errors and report them to the test runner without breaking the flow.

The PHP test specs are not discoverable by the use of wild-cards (*) in the Karma configuration file since they are URLs on the server. So we need to list them inpidually, insert code into the Karma configuration file that generates the list of URLs (if this is possible), or write a PHP script that acts as a middleman to provide the combined test code.

The latter option seems best since it automates the discovery of the test specs and avoids adding custom behaviour to the Karma files.

When we insert test result data into our Javascript, we want to avoid breaking the code due to new lines, and unescaped quotes. So we should filter the result text. And for PHP errors, aim to display only the text of the error report, stripping out HTML formatting tags.

And when we write the test specs in PHP, we want to reduce our chances of making typos and keep our code dry. So we will have methods that we can use to implement Describe and It so that our test specs look very similar in structure to what we would write in the Javascript environment. And these methods allow us to change how they work at one place of implementation should we wish to say output pretty code at some stage.

Writing Test Specs

See the example below which shows neatly indented code that folds nicely to expand and collapse in the Sublime Text Editor.

We include before.php to insert the Tester Class and configure the script.

We include the code file that we are testing.

We include mocks (that simulate functionality) of any code that is required for our unit under test to function. We don't include any other files, that are themselves subject to tests, because they may have bugs of their own.

Then we have a suite of tests built using the Tester Class methods.

Finally, we provide callback functions to exercise the code under test, and return test results.

We will write our test specs in PHP and store each one in it's own file with a name ending in Spec such as: myClassSpec.php.

Three functions (static methods Tester::method()) are used to create a test suite:

  • describe - used to output a description of a group of tests
  • it - used to describe a single test and compare a result to an expected value
  • func - used to specify a function that is run to generate a test result

The describe function

This function takes 2 or 3 parameters.

Parameter 1 is a text string to describe a group of tests.

Parameter 2 is a string that is returned from a describe function or a chain of concatenated it functions.

Parameter 3 is a boolean which should be set to true in the outermost describe function to cause the text to be displayed rather than returned.

The it function

This function takes 3 parameters.

Parameter 1 is a text string to describe a test.

Parameter 2 is a string that is returned from a callback function.

Parameter 3 is the expected result (number/boolean/string).

Note that a boolean value is displayed as a 1 for true or blank for false, so when a test fails, the result may be confusing. So a bool_to_string method is provided with the Tester Class which converts a boolean value to it's text representation of true or false.

The func function

This function takes 1 parameter, the name of a function to call. The called function returns the test result.

The purpose of this function is to wrap the code under test so that it does not break the Javascript output of the test script.

Directory Structure

Your development code is placed in a src directory. PHP test Specs are put in tests/php/specs/ and should be named as: *Spec.php where * is the name of the test suite.

Running Tests

The test setup is built from an NPM install of php-tester

The package.json file includes a test command which runs the karma test runner.

The script: test.php is what actually runs the PHP tests and outputs javascript code for processing by the test runner. So this needs to be accessed via a URL to the server that runs PHP scripts.

This URL is specified in the karma.conf.js file. You can test this URL in a web browser to ensure that it is working and produces test output results.

Once everything is set up, you may run the tests from the command line with: npm test from the root of your test environment.