CodeView
Back to article:
Base
Ko
legacy
Utils
<?php /* * Usage: * php drive_testrunner.php dirname [options1] * php drive_testrunner.php [options2] * where * options1 = ( --file FileNameSubstring | * --class TestClassNameSubstring)* * options2 = ( --dirname Directory | * --file FileNameSubstring | * --class TestClassNameSubstring)* * --file and --class options intersect -- use all found files unless --file is * specified. Use all found test classes unless --class is specified. * No option for filtering particular tests in a suite. */ require_once("PHPUnit/Framework.php" ); require_once("MyTestRunner.php"); require_once("MyTestFormatter.php"); function check_arg($candidate, $args, $category) { if (!$args[$category]) { return true; } $hasMatch = false; foreach ($args[$category] as $currCandidate) { if (stristr($candidate, $currCandidate)) { $hasMatch = true; break; } } //if (!$hasMatch) { // print("************ Didn't match $category $candidate\n"); //} return $hasMatch; } function get_suite_from_file($suite, $file, $checkBasename=true, $args) { if (!check_arg($file, $args, 'files')) { return; } $basename = basename($file); if ($checkBasename) { if (!preg_match('/.*test.*\./i', $basename)) { #print("File $basename doesn't look like a test file\n"); return; } } # Always load only .inc or .php files if (!preg_match('/.*\.(?:php|inc)$/i', $basename)) { #print("File $basename doesn't look like a PHP file\n"); return; } $before_classes = get_declared_classes(); #print("**************** About to load file $file from dir " . getcwd() . "\n"); $file_fs = preg_replace('/\\\\/', '/', $file); #print("**************** Actually $file_fs... \n"); require_once $file_fs; $after_classes = get_declared_classes(); $new_classes = array_diff($after_classes, $before_classes); foreach ($new_classes as $class) { if (preg_match('/(?:T|\\bt)est(?:$|[^a-z])/i', $class)) { # print "Adding class $class from file $file ($basename)\n"; if (check_arg($class, $args, 'classes')) { $suite->addTestSuite($class); } } } } function has_test_dir($dir_contents) { foreach ($dir_contents as $subdir) { if (preg_match('/^tests?$/i', $subdir)) { return $subdir; } } return null; } function is_test_dir($parent, $subdir) { return (preg_match('/^tests?$/i', $subdir) && is_dir("$parent/$subdir") ); } function is_possible_subdir_name($dir) { return $dir != '.' && $dir != '..' && $dir != '.svn'; } function get_suite_from_all_modules($suite, $directory, $subdir, $checkFilename, $args) { $fullname = "$directory/$subdir"; if (is_dir($fullname)) { $dh = opendir($fullname); if (!$dh) { return; } while (($file = readdir($dh)) != false) { if (is_possible_subdir_name($file)) { get_suite_from_all_modules($suite, $fullname, $file, $checkFilename, $args); } } closedir($dh); } else { get_suite_from_file($suite, $fullname, $checkFilename, $args); } } function get_suite_from_dir($directory, $args) { // Find all tests under dir $directory... // Introspect to pull out the test classes if (!is_dir($directory)) { // Maybe it's a file if (!file_exists($directory)) { print("Can't work with \$directory=$directory\n"); return $suite; } $suite = new PHPUnit_Framework_TestSuite(); get_suite_from_file($suite, $directory, true, $args); return $suite; } else { $suite = new PHPUnit_Framework_TestSuite(); // Look for a 'test' or 'tests' dir $members = scandir($directory); if (has_test_dir($members)) { # Just pick out the testdirs and walk their contents foreach ($members as $subdir) { if (is_test_dir($directory, $subdir)) { $curr_dir = getcwd(); chdir("$directory"); get_suite_from_all_modules($suite, ".", $subdir, false, $args); chdir($curr_dir); } } } $dh = opendir($directory); if (!$dh) { return $suite; } while (($file = readdir($dh)) != false) { if (is_possible_subdir_name($file)) { get_suite_from_all_modules($suite, $directory, $file, true, $args); } } closedir($dh); } return $suite; } # first arg is the directory to get tests from # --file fname -- if given, choose only matching files # --class test -- if given, choose only matching tests $dirname = null; $args = Array('dirname' => null, 'files' => Array(), 'classes' => Array() ); if ($argc <= 1) { $args['dirname'] = getcwd(); } else { if ($argc <= 3 && $argv[1] == "--dir") { $args['dirname'] = $argv[2]; $idx = 3; } else { $args['dirname'] = $argv[1]; $idx = 2; } while ($idx < $argc - 1) { switch ($argv[$idx]) { case '--file': $args['files'][] = $argv[$idx + 1]; $idx += 2; break; case '--class': $args['classes'][] = $argv[$idx + 1]; $idx += 2; break; default: print_error("drive_testrunner.php: Unrecognized comment-line argument $idx: $argv[$idx]"); return; } } if ($idx == $argc - 1) { print_error("drive_testrunner.php: Unhandled comment-line argument $idx: $argv[$idx]"); return; } } function print_error($msg) { print "@suite_started@: drive_testrunner.php\n"; print "@fault@: $msg\n"; print "@suite_finished@:\n"; } #print_r($args); $suite = get_suite_from_dir($args['dirname'], $args); if ($suite) { if ($suite->count() == 0) { print "@suite_started@: drive_testrunner.php: No PHP Unit tests selected\n"; if ($args['files']) { printf("@info@: No matching files in ['%s']\n", implode("', '", $args['files'])); } if ($args['classes']) { printf("@info@: No matching classes in ['%s']\n", implode("', '", $args['classes'])); } print "@suite_finished@:\n"; return; } $runner = new tests_TestRunner($suite); $formatter = new KoUnit_Formatter(); $runner->addFormatter($formatter); $runner->run(); } ?>