12

Drupal 8 is supplementing the testing framework based on Simpletest with PHPUnit, and Simpletest could be removed in Drupal 9.

I'm not upgrading yet to Drupal 8, but I was wondering how I can write existing tests in PHPUnit (to follow-up with the trend) for Drupal 7, instead in Simpletest?

Is there any method or module for integrating PHPUnit with Drupal 7?

There are few like phpunit or drunit, but they're not for Drupal 7.

  • 1
    Just want to throw Behat out there. It's great for doing real-world test scenarios (not really unit testing): drupal.org/project/drupalextension Once you get it setup, it makes testing Drupal functionality a breeze. We are running Behat in a CI environment and love it! – donutdan4114 Sep 13 '14 at 22:27
  • @donutdan4114 can you provide some more info or an instructional video showing how you accomplish this with Drupal? I am very interested. – zkent Jun 18 '15 at 18:42
11

You can get PHPUnit tests to run by bootstrapping Drupal within each of your test files. It's not ideal, but it does work.

define('DRUPAL_ROOT', 'your/path/to/drupal');
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';

// Bootstrap Drupal.
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

// Proceed with PHPUnit tests as usual from here.
class MyTest extends \PHPUnit_Framework_TestCase {
  ...
  • 4
    If you need to do this, what you are writing are not Unit Tests, and you should probably just use DrupalWebTestCase from the SimpleTest-based core testing module. – matt2000 Jul 2 '15 at 23:14
  • @matt2000 yea and wait hours until tests finished ... – Codium Feb 20 '18 at 14:22
3

PHPUnit provides a nice API for building the objects whereas the Drupal's simpletest doesn't. There is one library available in gist for integrating PHPUnit with Drupal 7.
To execute those scripts you need to checkout this gist-repository. To execute Unit-Tests in the command-line simply go to a Drupal site (ie. <DRUPAL_ROOT>/sites/default) and use dphpunit.bash just as you would use the phpunit command.

The script consists of 3 files:

  1. dphpunit.bash - which simply invokes drun-dphpunit.php with a few extra parameters. It's needed because PHP is incapable of dealing with symlinks correctly.
  2. drun-dphpunit.php - which is basically the same as the upstream phpunit runner, except that it handles the extra parameter.
  3. bootstrap.inc.php - which makes a Drupal bootstrap very similar to drush.

Source: http://devblog.more-onion.com/content/writing-unit-tests-drupal-7


bootstrap.inc.php

<?php

$path = CWD;

$site_dir = NULL;
$dpl_dir = NULL;

while ($path != '/') {
    if (file_exists($path . '/settings.php')) {
        $site_dir = $path;
    }
    if (file_exists($path . '/index.php') && file_exists($path . '/includes/bootstrap.inc')) {
        $dpl_dir = $path;
        break;
    }
    $path = dirname($path);
}

if (!$dpl_dir) {
    echo "No drupal directory found in or above current working directory. Aborting. \n";
    exit(1);
}
if (!$site_dir) {
    $site_dir = $dpl_dir . '/sites/default';
    if (!file_exists($site_dir . '/settings.php')) {
        echo "No configured site found. Aborting.\n";
        exit(1);
    }
}

$_SERVER['HTTP_HOST'] = basename($site_dir);
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';

define('DRUPAL_ROOT', $dpl_dir);
set_include_path($dpl_dir . PATH_SEPARATOR . get_include_path());
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

dphpunit.bash

#!/bin/bash

# get dirname of the script
DIR="$(dirname $(readlink "$0"))"

# assume the boostrap script is stored in the same directory
php "$DIR/drun-phpunit.php" "$(pwd)" --bootstrap "$DIR/bootstrap.inc.php" "$@"

drun-phpunit.php

<?php
require_once 'PHP/CodeCoverage/Filter.php';
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'PHPUNIT');

if (extension_loaded('xdebug')) {
  xdebug_disable();
}

if (strpos('/usr/bin/php', '@php_bin') === 0) {
  set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
}

require_once 'PHPUnit/Autoload.php';
define('PHPUnit_MAIN_METHOD', 'PHPUnit_TextUI_Command::main');
define('CWD', $_SERVER['argv'][1]);
unset($_SERVER['argv'][1]);

$command = new PHPUnit_TextUI_Command;
$command->run($_SERVER['argv']);

There is one more library available for integration PHPUnit with Drupal 7: https://github.com/sebastianbergmann/phpunit

More information about this scripts can be checked here: http://thomaslattimore.com/blog/using-phpunit-with-drupal-7

  • 5
    Sadly, this repo is gone. – sheldonkreger Feb 17 '15 at 22:58
  • 2
    -1 because gist is gone. – cwallenpoole Sep 23 '15 at 15:25
1

There is workaround with configuration file.

  1. Create phpunit.xml.dist file in your drupal project root. Got to contain this
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="phpunit.xsd"
         bootstrap="drupal_phpunit_bootstrap.php"
         verbose="true">

</phpunit>
  1. Phpunit has to bootstrap our drupal instance. Create drupal phpunit bootstrap file. I prefer to name it drupal_phpunit_bootstrap.php
<?php

$_SERVER['HTTP_HOST'] = 'your.url';
$_SERVER['SCRIPT_NAME'] = '/index.php';
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['SERVER_NAME'] = NULL;
$_SERVER['SERVER_SOFTWARE'] = NULL;
$_SERVER['HTTP_USER_AGENT'] = NULL;
// Fix for behat drupal instantiation.
define('DRUPAL_ROOT', dirname(realpath(__FILE__)));
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);

Gist: https://gist.github.com/permanovd/cb9c02920c49a29c97653f4f697147b1

Thats all. Now you can start your tests in several ways.

1. CLI

phpunit -c phpunit.xml.dist QuestionValidationValueOptionsInputTest /yoursite.dir/public_html/profiles/standard/modules/some_module/tests/QuestionValidationTest.php

where:

  • -c: Defines configuration file.
  • QuestionValidationValueOptionsInputTest and path: Defines test class name and path to it.

2. IDE (phpstorm)

You have to add test running configuration

Test run configuration

And no need to include drupal bootstrap code into every test.

Note

You may have problems with tests because of wrong php version of your environment.

Further reading:

https://phpunit.de/manual/current/en/organizing-tests.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.