Over a million developers have joined DZone.

Practical PHP Testing Patterns: Scripted Test

· Web Dev Zone

Make the transition to Node.js if you are a Java, PHP, Rails or .NET developer with these resources to help jumpstart your Node.js knowledge plus pick up some development tips.  Brought to you in partnership with IBM.

Scripted Test is the main classes of tests that are written nowadays: a reproduction of hypothetical client code, that asserts the called code works correctly.

Scripted Tests enable us to use Test-Driven Development, and transform tests in an instrument of design instead of a mere checklist.

The Scripted Test approach gives tests the same dignity of the production code: we write and refactor them as they were ordinary classes. In PHPUnit, which is the standard testing automation framework for PHP applications, they are always represented as classes, but also as files in other testing frameworks. Unless differently specified, we will always refer to PHPUnit..

By the way, Recorded Tests introduced in the previous article cannot bypass under the user interface hood. Test for groups of objects (cmmonly named functional tests) or single classes (unit tests) have to be written by hand in some way. This is not necessarily an issue, since we probably want to write them in advance to ensure the production code they exercise will be testable and well decoupled from the rest of the application. Focusing on the client's point of view is the best way to start designing an Api, being it a web service or the set of public methods of a single object.

Many years ago Scripted Tests were, as the name suggest, standalone scripts (especially in PHP, which is in turn tested with phpt, a basic testing framework), that exercised the code under test and raised visible warnings in case of failures. Now we can write them with a testing automation framework which provides us automatic isolation and results processing, along with small libraries for asserting and mocking.

This is an example of plain old test script.

require_once 'Sum.php';

$sum = new Sum(23, 42);
$result = $sum->getValue();
if ($result !== 65) {
    throw new Exception('Sum produces an incorrect result.');
echo "Sum is ok.\n";

Note how likely repeating the various if-exception combination and messages between the various tests would be. Also aggregating the output of several of this script is not going to be easy.

This is how phpt, the tool used for testing PHP itself, would approach the problem:

Sum class test
require_once 'Sum.php';

$sum = new Sum(23, 42);
$result = $sum->getValue();

phpt compares the ouput of the --FILE-- section execution with the --EXPECT-- section. PHP native functions are tested with lots of scripts like this, which are the first step towards the definition of independent Test Cases.

Here's how PHPUnit defines a Scripted Test instead:

require_once 'Sum.php';

class SumTest extends PHPUnit_Framework_TestCase
    public function testProducesCorrectResult()
        $sum = new Sum(23, 42);
        $result = $sum->getValue();
        $this->assertSame(65, $result);

The PHPUnit's executable (/usr/bin/phpunit when installed via PEAR) will happily take the file, instance the test case one time for each test method to run, and tell you how many assertion failed. PHPUnit cannot be used to test the php interpreter or its own core, however, because a regression would affect also the testing harness.

The solutions available for testing have evolved over the years, and now you don't have to resort to manually run scripts anymore. PHPUnit is the PHP version of the xUnit series of frameworks, and provide you with all you need to set up a sandbox for your tests and running them, gathering statistics and displaying failures in the format you choose.

Before diving into how to write test code, we'll see a couple more general patterns, such as the Data-Driven test.

Learn why developers are gravitating towards Node and its ability to retain and leverage the skills of JavaScript developers and the ability to deliver projects faster than other languages can.  Brought to you in partnership with IBM.


Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}