VGTech is a blog where the developers and devops of Norways most visited website share code and tricks of the trade… Read more



Are you brilliant? We're hiring. Read more

Using PHP’s built-in web server in your test suites

PHP

As of PHP-5.4.0 the CLI SAPI provides a built-in web server. The web server is designed for development purposes, and serves requests sequentially. This web server can come in really handy when the need for an httpd arises during (integration) tests.

In this post I’ll use PHPUnit as the testing framework, and I’ll show you how to start the web server during the bootstrap process, and how to shut it down when the test suite is finished.

PHPUnit lets you specify a bootstrap file that is executed before the tests. This bootstrap file will contain the code needed to start and stop the web server. First, specify a bootstrap file in PHPUnit’s XML configuration file:

Show code
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./tests/bootstrap.php">
  <testsuites>
    <testsuite name="Name of the test suite">
      <directory>./tests</directory>
    </testsuite>
  </testsuites>
  <php>
    <const name="WEB_SERVER_HOST" value="localhost" />
    <const name="WEB_SERVER_PORT" value="1349" />
    <const name="WEB_SERVER_DOCROOT" value="./public" />
  </php>
</phpunit>

The three constants we define holds the host and the port that the server will listen on (localhost:1349) and the path to the document root (./public). These constants will be used in our bootstrap.php script when starting up the web server.

Now, on to the bootstrap script:

Show code
<?php
// Command that starts the built-in web server
$command = sprintf(
    'php -S %s:%d -t %s >/dev/null 2>&1 & echo $!',
    WEB_SERVER_HOST,
    WEB_SERVER_PORT,
    WEB_SERVER_DOCROOT
);

// Execute the command and store the process ID
$output = array(); 
exec($command, $output);
$pid = (int) $output[0];

echo sprintf(
    '%s - Web server started on %s:%d with PID %d', 
    date('r'),
    WEB_SERVER_HOST, 
    WEB_SERVER_PORT, 
    $pid
) . PHP_EOL;

// Kill the web server when the process ends
register_shutdown_function(function() use ($pid) {
    echo sprintf('%s - Killing process with ID %d', date('r'), $pid) . PHP_EOL;
    exec('kill ' . $pid);
});

// More bootstrap code

With this bootstrap script the web server will be started before the tests execute, and when the test suite is finished the shutdown function will kill the web server process.

If you execute PHPUnit with the above XML configuration and the bootstrap file you should see something like this:

Show code
Fri, 19 Jul 2013 11:09:09 +0200 - Web server started on localhost (port 1349) with PID 9877
PHPUnit 3.7.22 by Sebastian Bergmann.

Configuration read from /path/to/phpunit.xml.dist



Time: 0 seconds, Memory: 1.75Mb

No tests executed!
Fri, 19 Jul 2013 11:09:09 +0200 - Killing process with ID 9877

SUCCESS!

If you have any other use cases for the built-in web server, feel free to leave a comment.

Senior developer at VG. Coder of code, drinker/brewer of beer and listener of metal/punk/hc. @cogocogo | @BeerNorway | www.beernorway.com


7 comments

Leave your comment