Index: modules/simpletest/simpletest.info =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.info,v retrieving revision 1.4 diff -u -r1.4 simpletest.info --- modules/simpletest/simpletest.info 11 Oct 2008 02:33:01 -0000 1.4 +++ modules/simpletest/simpletest.info 18 Feb 2009 08:10:53 -0000 @@ -5,4 +5,5 @@ version = VERSION core = 7.x files[] = simpletest.module +files[] = simpletest.test.inc files[] = simpletest.install Index: modules/simpletest/simpletest.module =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v retrieving revision 1.36 diff -u -r1.36 simpletest.module --- modules/simpletest/simpletest.module 13 Feb 2009 00:39:01 -0000 1.36 +++ modules/simpletest/simpletest.module 18 Feb 2009 08:10:53 -0000 @@ -2,6 +2,11 @@ // $Id: simpletest.module,v 1.36 2009/02/13 00:39:01 webchick Exp $ /** + * @file + * Provides testing framework module base. + */ + +/** * Implementation of hook_help(). */ function simpletest_help($path, $arg) { @@ -89,7 +94,7 @@ $header = array(t('Message'), t('Group'), t('Filename'), t('Line'), t('Function'), array('colspan' => 2, 'data' => t('Status'))); while ($result = db_fetch_object($results)) { $class = $result->test_class; - $info = $uncategorized_tests[$class]->getInfo(); + $info = $uncategorized_tests[$class]; $group = $info['group']; $selected_tests[$group][$class] = TRUE; if (!isset($group_summary[$group])) { @@ -133,7 +138,7 @@ foreach ($form['results'] as $group => &$elements) { $group_ok = TRUE; foreach ($elements as $class => &$element) { - $info = $uncategorized_tests[$class]->getInfo(); + $info = $uncategorized_tests[$class]; $ok = $element['summary']['#fail'] + $element['summary']['#exception'] == 0; $element += array( '#type' => 'fieldset', @@ -169,9 +174,7 @@ $form['tests']['table'][$group_name] = array( '#collapsed' => TRUE, ); - foreach ($test_group as $test) { - $test_info = $test->getInfo(); - $test_class = get_class($test); + foreach ($test_group as $test_class => $test_info) { $is_selected = isset($selected_tests[$group_name][$test_class]); $form['tests']['table'][$group_name][$test_class] = array( '#type' => 'checkbox', @@ -324,21 +327,26 @@ * Run selected tests. */ function simpletest_test_form_submit($form, &$form_state) { - // Ensure that all classes are loaded before we create instances to get test information and run. - simpletest_get_all_tests(); - // Get list of tests. - $tests_list = array(); - foreach ($form_state['values'] as $class_name => $value) { - if (class_exists($class_name) && $value === 1) { - $tests_list[] = $class_name; + $test_classes = array(); + foreach ($form_state['values'] as $test_class => $value) { + if ($value === 1) { + // Load test file and ensure that test class exists. + simpletest_load_test($test_class); + if (class_exists($test_class)) { + $test_classes[] = $test_class; + } + else { + drupal_set_message(t('No such test class @class.', array('@class' => $test_class)), 'error'); + } } } - if (count($tests_list) > 0 ) { - simpletest_run_tests($tests_list, 'drupal'); + + if ($test_classes) { + simpletest_run_tests($test_classes, 'drupal'); } else { - drupal_set_message(t('No test(s) selected.'), 'error'); + drupal_set_message(t('No test(s) to run.'), 'error'); } } @@ -353,13 +361,13 @@ */ function simpletest_run_tests($test_list, $reporter = 'drupal') { cache_clear_all(); + $tests = simpletest_get_all_tests(); $test_id = db_insert('simpletest_test_id')->useDefaults(array('test_id'))->execute(); // Get the info for the first test being run. $first_test = array_shift($test_list); - $first_instance = new $first_test(); + $info = $tests[$first_test]; array_unshift($test_list, $first_test); - $info = $first_instance->getInfo(); $batch = array( 'title' => t('Running SimpleTests'), @@ -386,9 +394,6 @@ * Batch operation callback. */ function _simpletest_batch_operation($test_list_init, $test_id, &$context) { - // Ensure that all classes are loaded before we unserialize some instances. - simpletest_get_all_tests(); - // Get working values. if (!isset($context['sandbox']['max'])) { // First iteration: initialize working values. @@ -405,10 +410,15 @@ // Perform the next test. $test_class = array_shift($test_list); + + // Get test info and load test file. + $tests = simpletest_get_all_tests(); + $info = $tests[$test_class]; + simpletest_load_test($test_class); + $test = new $test_class($test_id); $test->run(); $size = count($test_list); - $info = $test->getInfo(); // Gather results and compose the report. $test_results[$test_class] = $test->results; @@ -450,46 +460,29 @@ * Get a list of all of the tests. * * @return - * An array of tests, with the class name as the keys and the instantiated - * versions of the classes as the values. + * An array of tests, with the test class name as the keys and the test + * information as the value. + * @see hook_test() */ function simpletest_get_all_tests() { - static $formatted_classes; - if (!isset($formatted_classes)) { - require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'simpletest') . '/drupal_web_test_case.php'; - $files = array(); - foreach (array_keys(module_rebuild_cache()) as $module) { - $module_path = drupal_get_path('module', $module); - $test = $module_path . "/$module.test"; - if (file_exists($test)) { - $files[] = $test; - } + static $tests; - $tests_directory = $module_path . '/tests'; - if (is_dir($tests_directory)) { - foreach (file_scan_directory($tests_directory, '/\.test$/') as $file) { - $files[] = $file->filename; + if (!isset($tests)) { + // Manually call each module so that we can know which module a given test + // came from. + $tests = array(); + foreach (module_implements('test', TRUE) as $module) { + $test_classes = module_invoke($module, 'test'); + if (isset($test_classes) && is_array($test_classes)) { + foreach (array_keys($test_classes) as $test_class) { + $test_classes[$test_class]['module'] = $module; } + $tests = array_merge($tests, $test_classes); } } - - $existing_classes = get_declared_classes(); - foreach ($files as $file) { - include_once DRUPAL_ROOT . '/' . $file; - } - $classes = array_values(array_diff(get_declared_classes(), $existing_classes)); - $formatted_classes = array(); - foreach ($classes as $key => $class) { - if (method_exists($class, 'getInfo')) { - $formatted_classes[$class] = new $class; - } - } - } - if (count($formatted_classes) == 0) { - drupal_set_message('No test cases found.', 'error'); - return FALSE; } - return $formatted_classes; + + return $tests; } /** @@ -501,15 +494,29 @@ */ function simpletest_categorize_tests($tests) { $groups = array(); - foreach ($tests as $test => $instance) { - $info = $instance->getInfo(); - $groups[$info['group']][$test] = $instance; + foreach ($tests as $test_case => $info) { + $groups[$info['group']][$test_case] = $info; } uksort($groups, 'strnatcasecmp'); return $groups; } /** + * Load test file of specified test class. Also includes the DrupalWebTestCase. + * + * @param $test_class + * Test class to load file for. + */ +function simpletest_load_test($test_class) { + module_load_include('php', 'simpletest', 'drupal_web_test_case'); + $tests = simpletest_get_all_tests(); + + $info = $tests[$test_class]; + require_once drupal_get_path('module', $info['module']) . '/' . + (isset($info['file']) ? 'tests/' . $info['file'] : $info['module']) . '.test'; +} + +/** * Remove all temporary database tables and directories. */ function simpletest_clean_environment() { Index: modules/simpletest/simpletest.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.test,v retrieving revision 1.16 diff -u -r1.16 simpletest.test --- modules/simpletest/simpletest.test 22 Jan 2009 12:46:06 -0000 1.16 +++ modules/simpletest/simpletest.test 18 Feb 2009 08:10:53 -0000 @@ -13,17 +13,6 @@ */ protected $test_ids = array(); - function getInfo() { - return array( - 'name' => t('SimpleTest functionality'), - 'description' => t('Test SimpleTest\'s web interface: check that the intended tests were - run and ensure that test reports display the intended results. Also - test SimpleTest\'s internal browser and API\'s both explicitly and - implicitly.'), - 'group' => t('SimpleTest') - ); - } - function setUp() { if (!$this->inCURL()) { parent::setUp('simpletest'); @@ -231,7 +220,8 @@ */ function getResultFieldSet() { $fieldsets = $this->xpath('//fieldset'); - $info = $this->getInfo(); + $tests = simpletest_get_all_tests(); + $info = $tests[get_class($this)]; foreach ($fieldsets as $fieldset) { if ($fieldset->legend == $info['group']) { return $fieldset; Index: scripts/run-tests.sh =================================================================== RCS file: /cvs/drupal/drupal/scripts/run-tests.sh,v retrieving revision 1.23 diff -u -r1.23 run-tests.sh --- scripts/run-tests.sh 1 Feb 2009 16:42:26 -0000 1.23 +++ scripts/run-tests.sh 18 Feb 2009 08:10:53 -0000 @@ -52,11 +52,9 @@ // Display all available tests. echo "\nAvailable test groups & classes\n"; echo "-------------------------------\n\n"; - foreach ($groups as $group => $tests) { - echo $group . "\n"; - foreach ($tests as $class_name => $instance) { - $info = $instance->getInfo(); - echo " - " . $info['name'] . ' (' . $class_name . ')' . "\n"; + foreach ($groups as $group_name => $test_group) { + foreach ($test_group as $test_class => $test_info) { + echo " - " . $test_info['name'] . ' (' . $class_name . ')' . "\n"; } } exit; @@ -343,10 +341,12 @@ * Run a single test (assume a Drupal bootstrapped environment). */ function simpletest_script_run_one_test($test_id, $test_class) { - simpletest_get_all_tests(); + simpletest_load_test($test_class); + $tests = simpletest_get_all_tests(); + $info = $tests[$test_class]; + $test = new $test_class($test_id); $test->run(); - $info = $test->getInfo(); $status = ((isset($test->results['#fail']) && $test->results['#fail'] > 0) || (isset($test->results['#exception']) && $test->results['#exception'] > 0) ? 'fail' : 'pass'); @@ -443,7 +443,7 @@ else { echo "Tests to be run:\n"; foreach ($test_list as $class_name) { - $info = $all_tests[$class_name]->getInfo(); + $info = $all_tests[$class_name]; echo " - " . $info['name'] . ' (' . $class_name . ')' . "\n"; } echo "\n"; Index: modules/simpletest/simpletest.api.php =================================================================== RCS file: modules/simpletest/simpletest.api.php diff -N modules/simpletest/simpletest.api.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/simpletest/simpletest.api.php 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,53 @@ + t('Example'), + 'description' => t('Tests example stuff.'), + 'group' => t('Example'), + ); + + // File additional_example.test found in /path/to/module/tests directory. + $tests['AdditionalExampleTestCase'] = array( + 'name' => t('Additional example'), + 'description' => t('Tests additional example stuff.'), + 'group' => t('Example'), + 'file' => 'additional_example', + ); + + return $tests; +} + +/** + * @} End of "addtogroup hooks". + */ Index: modules/simpletest/simpletest.test.inc =================================================================== RCS file: modules/simpletest/simpletest.test.inc diff -N modules/simpletest/simpletest.test.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/simpletest/simpletest.test.inc 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,25 @@ + t('SimpleTest functionality'), + 'description' => t('Test SimpleTest\'s web interface: check that the intended tests were + run and ensure that test reports display the intended results. Also + test SimpleTest\'s internal browser and API\'s both explicitly and + implicitly.'), + 'group' => t('SimpleTest') + ); + + return $tests; +}