#!/usr/bin/php <?php // $Id$ /** * @file * This script runs Drupal tests from command line. * You can provide groups or class names of the tests you wish to run. * For example: php scripts/run-functional-tests.sh Profile * If no arguments are provided, the help text will print. */ $reporter = 'text'; $test_names = array(); $host = 'localhost'; $path = ''; $script = basename(array_shift($_SERVER['argv'])); if (in_array('--help', $_SERVER['argv']) || empty($_SERVER['argv'])) { echo <<<EOF Run Drupal tests from the shell. Usage: {$script} [OPTIONS] <tests> Example: {$script} Profile All arguments are long options. --help Print this page. --clean Cleans up database tables or directories from previous, failed, tests and then exits (no tests are run). --url Immediately preceeds a URL to set the host and path. You will need this parameter if Drupal is in a subdirectory on your localhost and you have not set \$base_url in settings.php. --reporter Immediatly preceeds the name of the output reporter to use. This Defaults to "text", while other options include "xml" and "html". --all Run all available tests. --class Run tests identified by speficic class names. <test1>[,<test2>[,<test3> ...]] One or more tests to be run. By default, these are interpreted as the names of test groups as shown at ?q=admin/build/testing. These group names typically correspond to module names like "User" or "Profile" or "System", but there is also a group "XML-RPC". If --class is specified then these are interpreted as the names of specific test classes whose test methods will be run. Tests must be separated by commas. Ignored if --all is specified. To run this script you will normally invoke it from the root directory of your Drupal installation as php ./scripts/{$script} \n EOF; exit; } $clean = FALSE; $all = FALSE; $class_names = FALSE; $test_names = array(); while ($param = array_shift($_SERVER['argv'])) { switch ($param) { case '--url': $url = array_shift($_SERVER['argv']); $parsed = parse_url($url); $host = $parsed['host']; $path = $parsed['path']; break; case '--all': $all = TRUE; break; case '--class': $class_names = TRUE; break; case '--clean': $clean = TRUE; break; case '--reporter': $reporter = array_shift($_SERVER['argv']); if (!in_array($reporter, array("text", "xml", "html"))) { $reporter = "text"; } break; default: $test_names += explode(',', $param); break; } } $_SERVER['HTTP_HOST'] = $host; $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $_SERVER['SERVER_ADDR'] = '127.0.0.1'; $_SERVER['SERVER_SOFTWARE'] = 'Apache'; $_SERVER['SERVER_NAME'] = 'localhost'; $_SERVER['REQUEST_URI'] = $path .'/'; $_SERVER['SCRIPT_NAME'] = $path .'/index.php'; $_SERVER['PHP_SELF'] = $path .'/index.php'; $_SERVER['HTTP_USER_AGENT'] = 'Drupal command line'; chdir(realpath(dirname(__FILE__) . '/..')); require_once './includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); if (!module_exists('simpletest')) { echo("ERROR: The simpletest module must be enabled before this script can run.\n"); exit; } if ($clean) { // Clean up left-over times and directories. simpletest_clean_environment(); // Get the status messages and print them. $messages = array_pop(drupal_get_messages('status')); foreach($messages as $text) { echo("- " . $text . "\n"); } exit; } // Run tests as user #1. $GLOBALS['user'] = user_load(1); //Load simpletest files $total_test = &simpletest_get_total_test(); $test_instances = $total_test->getTestInstances(); if ($all) { $test_list = NULL; } else { if ($class_names) { $test_list = _run_tests_check_classes($test_names, $test_instances); } else { $test_list = _run_tests_find_classes($test_names, $test_instances); } } if (empty($test_list) && !$all) { echo("ERROR: No valid tests were specified.\n"); exit; } // If not in 'safe mode', increase the maximum execution time: if (!ini_get('safe_mode')) { set_time_limit(360); } // Tell the user about what tests are to be run. if (!$all && $reporter == 'text') { echo("Tests to be run:\n"); foreach ($test_list as $name) { echo("- " . $name . "\n"); } echo("\n"); } simpletest_run_tests(array_keys($test_list), $reporter); // Utility functions: /** * Check that each class name exists as a test, return the list of valid ones. */ function _run_tests_check_classes($test_names, $test_instances) { $test_list = array(); $test_names = array_flip($test_names); foreach ($test_instances as $group_test) { $tests = $group_test->getTestInstances(); foreach ($tests as $test) { $class = get_class($test); $info = $test->getInfo(); if (isset($test_names[$class])) { $test_list[$class] = $info['name']; } } } return $test_list; } /** * Check that each group name exists, return the list of class in valid groups. */ function _run_tests_find_classes($test_names, &$test_instances) { $test_list = array(); $test_names = array_flip($test_names); uasort($test_instances, 'simpletest_compare_instances'); foreach ($test_instances as $group_test) { $group = $group_test->getLabel(); if (isset($test_names[$group])) { $tests = $group_test->getTestInstances(); foreach ($tests as $test) { $info = $test->getInfo(); $test_list[get_class($test)] = $info['name']; } } } return $test_list; }