summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/run-functional-tests.sh186
1 files changed, 169 insertions, 17 deletions
diff --git a/scripts/run-functional-tests.sh b/scripts/run-functional-tests.sh
index 56a0da6d2..669edc836 100755
--- a/scripts/run-functional-tests.sh
+++ b/scripts/run-functional-tests.sh
@@ -4,30 +4,93 @@
/**
* @file
- * This script can be run with browser or from command line.
- * You can provide class names of the tests you wish to run.
- * When this script is run from browser you can select which reporter to use html or xml.
- * For command line: php run_functional_tests.php SearchMatchTest,ProfileModuleTestSingle
- * For browser: http://yoursite.com/sites/all/modules/simpletest/run_all_tests.php?include=SearchMatchTest,ProfileModuleTestSingle&reporter=html
- * If none of these two options are provided all tests will be run.
+ * 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.
*/
-$tests = NULL;
$reporter = 'text';
+$test_names = array();
$host = 'localhost';
$path = '';
-array_shift($_SERVER['argv']); // throw away script name
+$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']);
- $parse = parse_url($url);
- $host = $parse['host'];
- $path = $parse['path'];
+ $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:
- $tests = explode(',', $param);
+ $test_names += explode(',', $param);
break;
}
}
@@ -46,13 +109,102 @@ chdir(realpath(dirname(__FILE__) . '/..'));
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
-//load simpletest files
-simpletest_load();
+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);
}
-simpletest_run_tests($tests, $reporter);
-?>
+// 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;
+}
+