diff --git a/modules/simpletest/API.txt b/modules/simpletest/API.txt new file mode 100644 index 0000000..1c5c82e --- /dev/null +++ b/modules/simpletest/API.txt @@ -0,0 +1,15 @@ + +DESCRIPTION +----------- +Provides a reference of the API changes between SimpleTest 7.x-1.x include with +Drupal 7 core and SimpleTest 7.x-2.x. + +CHANGES +------- + * The DrupalWebTestCase::setUp() method no longer accepts a variable number of + arguments, instead it only accepts an array of the modules to be enabled. + + * Modules that provided 2.x compatible tests are required to add the following + attribute to their info file. + + testing_api = 2.x diff --git a/modules/simpletest/CHANGELOG.txt b/modules/simpletest/CHANGELOG.txt new file mode 100644 index 0000000..821c1d0 --- /dev/null +++ b/modules/simpletest/CHANGELOG.txt @@ -0,0 +1,32 @@ + +SimpleTest 7.x-2.x, xxxx-xx-xx (development version) +------------------------------ +- Changes: + * #610072: setUp() function accepting array as arguments. + * #610072: followup. + * #550752: Detect cache our of sync with code on test list select. + * Remove version attribute form .info file. + * Place hook_schema() first in .install. + * #588084: Provide a mechanism for leaving prefix tables. + * Add API.txt to document API changes. + * Add variable delete for 'simpletest_remove_tables'. + * Remove core tests since 7.x-2.x is not going to maintain them. + * Added check for 2.x compatible tests. + * Add testing API switching mechanism. + * Cleanup non 2.x compatible test file removal. + * Remove 2.x compatible tests when in 1.x mode. + * Add testing API 2.x flag to simpletest.info. + * Add group to fieldset title when displaying results. + * Formatting and method scope additions. + * Add file documentation. + * Re-roll patch. + * When finding the test result fieldset include the test group. + * Cleanup test info. + * Merge changes from Drupal 7 core. + * Make alert() message more logical. + * Post merge fix. + * Modified versions of #666956 and #758662. + * Add setting field for remote_url and change all working from staging to remote. + * Add remote prefix to all randomly generated strings. + * Change function_get_args() to func_get_args(). + * Add setUrl() and resetUrl() to DrupalRemoteTestCase. diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php index a0cd114..ea08361 100644 --- a/modules/simpletest/drupal_web_test_case.php +++ b/modules/simpletest/drupal_web_test_case.php @@ -13,6 +13,11 @@ global $drupal_test_info; /** + * @file + * Provides DrupalTestCase, DrupalUnitTestCase, and DrupalWebTestCase classes. + */ + +/** * Base class for Drupal tests. * * Do not extend this class, use one of the subclasses in this file. @@ -1253,6 +1258,7 @@ class DrupalWebTestCase extends DrupalTestCase { $this->originalLanguageDefault = variable_get('language_default'); $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files'); $this->originalProfile = drupal_get_profile(); + $this->removeTables = variable_get('simpletest_remove_tables', TRUE); $clean_url_original = variable_get('clean_url', 0); // Save and clean shutdown callbacks array because it static cached and @@ -1289,6 +1295,47 @@ class DrupalWebTestCase extends DrupalTestCase { $test_info['test_run_id'] = $this->databasePrefix; $test_info['in_child_site'] = FALSE; + $this->setUpInstall(func_get_args(), $public_files_directory, $private_files_directory, $temp_files_directory); + + // Rebuild caches. + drupal_static_reset(); + drupal_flush_all_caches(); + + // Register actions declared by any modules. + actions_synchronize(); + + // Reload global $conf array and permissions. + $this->refreshVariables(); + $this->checkPermissions(array(), TRUE); + + // Reset statically cached schema for new database prefix. + drupal_get_schema(NULL, TRUE); + + // Run cron once in that environment, as install.php does at the end of + // the installation process. + drupal_cron_run(); + + // Log in with a clean $user. + $this->originalUser = $user; + drupal_save_session(FALSE); + $user = user_load(1); + + $this->setUpVariables($clean_url_original); + + // Set up English language. + unset($GLOBALS['conf']['language_default']); + $language = language_default(); + + // Use the test mail class instead of the default mail handler class. + variable_set('mail_system', array('default-system' => 'TestingMailSystem')); + + drupal_set_time_limit($this->timeLimit); + } + + /** + * Perform Drupal installation. + */ + protected function setUpInstall(array $modules, $public_files_directory, $private_files_directory, $temp_files_directory) { include_once DRUPAL_ROOT . '/includes/install.inc'; drupal_install_system(); @@ -1310,7 +1357,6 @@ class DrupalWebTestCase extends DrupalTestCase { // either a single array argument or a variable number of string arguments. // @todo Remove this compatibility layer in Drupal 8, and only accept // $modules as a single array argument. - $modules = func_get_args(); if (isset($modules[0]) && is_array($modules[0])) { $modules = $modules[0]; } @@ -1337,20 +1383,17 @@ class DrupalWebTestCase extends DrupalTestCase { $this->originalUser = $user; drupal_save_session(FALSE); $user = user_load(1); + } + /** + * Set post-installation variables. + */ + protected function setUpVariables($clean_url_original) { // Restore necessary variables. variable_set('install_task', 'done'); variable_set('clean_url', $clean_url_original); variable_set('site_mail', 'simpletest@example.com'); variable_set('date_default_timezone', date_default_timezone_get()); - // Set up English language. - unset($GLOBALS['conf']['language_default']); - $language = language_default(); - - // Use the test mail class instead of the default mail handler class. - variable_set('mail_system', array('default-system' => 'TestingMailSystem')); - - drupal_set_time_limit($this->timeLimit); } /** @@ -2128,7 +2171,7 @@ class DrupalWebTestCase extends DrupalTestCase { */ protected function handleForm(&$post, &$edit, &$upload, $submit, $form) { // Retrieve the form elements. - $elements = $form->xpath('.//input[not(@disabled)]|.//textarea[not(@disabled)]|.//select[not(@disabled)]'); + $elements = $form->xpath('.//input[not(@disabled)]|.//textarea[not(@disabled)]|.//select[not(@disabled)]|.//button[not(@disabled)]'); $submit_matches = FALSE; foreach ($elements as $element) { // SimpleXML objects need string casting all the time. @@ -2363,7 +2406,7 @@ class DrupalWebTestCase extends DrupalTestCase { * TRUE if the assertion succeeded, FALSE otherwise. */ protected function assertLink($label, $index = 0, $message = '', $group = 'Other') { - $links = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $label)); + $links = $this->xpath('//a[normalize-space(text())=:label]|//a[.//*[normalize-space(text())=:label]]', array(':label' => $label)); $message = ($message ? $message : t('Link with label %label found.', array('%label' => $label))); return $this->assert(isset($links[$index]), $message, $group); } @@ -2383,7 +2426,7 @@ class DrupalWebTestCase extends DrupalTestCase { * TRUE if the assertion succeeded, FALSE otherwise. */ protected function assertNoLink($label, $message = '', $group = 'Other') { - $links = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $label)); + $links = $this->xpath('//a[normalize-space(text())=:label]|//a[.//*[normalize-space(text())=:label]]', array(':label' => $label)); $message = ($message ? $message : t('Link with label %label not found.', array('%label' => $label))); return $this->assert(empty($links), $message, $group); } @@ -2445,7 +2488,7 @@ class DrupalWebTestCase extends DrupalTestCase { */ protected function clickLink($label, $index = 0) { $url_before = $this->getUrl(); - $urls = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $label)); + $urls = $this->xpath('//a[normalize-space(text())=:label]|//a[.//*[normalize-space(text())=:label]]', array(':label' => $label)); if (isset($urls[$index])) { $url_target = $this->getAbsoluteUrl($urls[$index]['href']); @@ -3373,6 +3416,342 @@ class DrupalWebTestCase extends DrupalTestCase { } } + +/** + * Clone an existing database and use it for testing. + */ +class DrupalCloneTestCase extends DrupalWebTestCase { + + /** + * Tables to exlude during data cloning, only their structure will be cloned. + * + * @var array + */ + protected $excludeTables = array( + 'cache', + 'cache_block', + 'cache_bootstrap', + 'cache_field', + 'cache_filter', + 'cache_form', + 'cache_image', + 'cache_menu', + 'cache_page', + 'cache_path', + 'cache_update', + 'watchdog', + ); + + protected function setUpInstall() { + global $db_prefix; + + // Store new database prefix. + $db_prefix_new = $db_prefix; + $db_prefix = $this->originalPrefix; + + // Rebuild schema based on prefixed database and such. + $schemas = drupal_get_schema(NULL, TRUE); + // Create a list of prefixed source table names. + $sources = array(); + foreach ($schemas as $name => $schema) { + $sources[$name] = Database::getConnection()->prefixTables('{' . $name . '}'); + } + + // Return to new prefix before performing cloning. + $db_prefix = $db_prefix_new; + + // Clone each table into the new database. + foreach ($schemas as $name => $schema) { + $this->cloneTable($name, $sources[$name], $schema); + } + } + + protected function setUpVariables() { + // Do nothing. + } + + /** + * Clone an existing table structure and data. + * + * @param $name + * Table name. + * @param $source + * Source table name. + * @param $schema + * A Schema API definition array. + */ + protected function cloneTable($name, $source, $schema) { + db_create_table($name, $schema); + + $target = Database::getConnection()->prefixTables('{' . $name . '}'); + if (!in_array($name, $this->excludeTables)) { + db_query('INSERT INTO ' . $target . ' SELECT * FROM ' . $source); + } + } +} + +/** + * Base class used for writing atomic remote tests. + * + * The test cases are written in such a way that they can be run against a + * staging or live environment and will clean up after themselves by reverting + * all peformed actions. The tests should be performed through a set of actions + * defined in the test method. For example: + * + * protected function testFoo() { + * $this->actions[] = 'login'; + * } + * + * protected function performLogin(); + * protected function revertLogin(); + * + * + * The setUp() and tearDown() methods will not create an environment, but + * instead direct the internal browser to the remote URL, + * 'simpletest_remote_url'. The tests will be run against the specified URL + * instead of the local machine. + * + * The test can also be run against the local development environment by + * leaving the variable blank. If not specified the remote URL will be filled + * with the local environment's URL. + */ +class DrupalRemoteTestCase extends DrupalWebTestCase { + + /** + * URL variables that need to be changed when running against remote server. + * + * @var array + */ + protected static $URL_VARIABLES = array('base_url', 'base_secure_url', 'base_insecure_url'); + + /** + * Prefix to be added to all random strings. + */ + protected static $REMOTE_PREFIX; + + /** + * URL of the remote server. + * + * @var string + */ + protected $remoteUrl; + + /** + * Associative array of original values for the URL variables. + * + * @var array + */ + protected $originalUrls = array(); + + /** + * List of actions to perform. + * + * @var array + */ + protected $actions = array(); + + /** + * Determine when to run against remote environment. + */ + protected function setUp() { +// // BEGIN: Excerpt from DrupalUnitTestCase. +// global $conf; +// + // Set to that verbose mode works properly. + $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files'); +// +// spl_autoload_register('db_autoload'); +// +// // Reset all statics so that test is performed with a clean environment. +// drupal_static_reset(); +// +// // Generate temporary prefixed database to ensure that tests have a clean starting point. +// $this->databasePrefix = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}'); +// $conf['file_public_path'] = $this->originalFileDirectory . '/' . $this->databasePrefix; +// + // Clone the current connection and replace the current prefix. + $connection_info = Database::getConnectionInfo('default'); + Database::renameConnection('default', 'simpletest_original_default'); + foreach ($connection_info as $target => $value) { + $connection_info[$target]['prefix'] = array( + 'default' => $value['prefix']['default'] . $this->databasePrefix, + ); + } + Database::addConnectionInfo('default', 'default', $connection_info['default']); +// +// // Set user agent to be consistent with web test case. +// $_SERVER['HTTP_USER_AGENT'] = $this->databasePrefix; +// +// // If locale is enabled then t() will try to access the database and +// // subsequently will fail as the database is not accessible. +// $module_list = module_list(); +// if (isset($module_list['locale'])) { +// $this->originalModuleList = $module_list; +// unset($module_list['locale']); +// module_list(TRUE, FALSE, FALSE, $module_list); +// } +// // END: Excerpt from DrupalUnitTestCase. + + if (!$this->remoteUrl && !($this->remoteUrl = variable_get('simpletest_remote_url', FALSE))) { + $this->remoteUrl = url('', array('absolute' => TRUE)); + } + // Point the internal browser to the staging site. + foreach (self::$URL_VARIABLES as $variable) { + $this->originalUrls[$variable] = $GLOBALS[$variable]; + $GLOBALS[$variable] = $this->remoteUrl; + } + $GLOBALS['base_secure_url'] = str_replace('http://', 'https://', $GLOBALS['base_secure_url']); + + // Generate unique remote prefix. + self::$REMOTE_PREFIX = 'test' . mt_rand(100, 100000); + + // Set the time-limit for the test case. + drupal_set_time_limit($this->timeLimit); + } + + /** + * Perform and revert actions, then tear down based on what setUp() did. + */ + protected function tearDown() { + // Perform all actions as part of the test and revert them. + $this->performActions(); + $this->revertActions(); + + // Revert all URL variables to their original values. + foreach (self::$URL_VARIABLES as $variable) { + $GLOBALS[$variable] = $this->originalUrls[$variable]; + } + + // BEGIN: Excerpt from DrupalUnitTestCase. + global $conf; + + // Get back to the original connection. + Database::removeConnection('default'); + Database::renameConnection('simpletest_original_default', 'default'); + + $conf['file_public_path'] = $this->originalFileDirectory; +// // Restore modules if necessary. +// if (isset($this->originalModuleList)) { +// module_list(TRUE, FALSE, FALSE, $this->originalModuleList); +// } +// // END: Excerpt from DrupalUnitTestCase. + } + + /** + * Perform all actions listed in the $actions array. + */ + protected function performActions() { + foreach ($this->actions as $action) { + call_user_func(array($this, 'perform' . ucfirst($action))); + } + } + + /** + * Revert all actions listed in the $actions array. + */ + protected function revertActions() { + foreach ($this->actions as $action) { + if (method_exists($this, 'revert' . ucfirst($action))) { + call_user_func(array($this, 'revert' . ucfirst($action))); + } + } + } + + /** + * Set the user agent to Drupal. + */ + protected function curlInitialize() { + parent::curlInitialize(); + curl_setopt($this->curlHandle, CURLOPT_USERAGENT, 'Drupal (+http://drupal.org/)'); + } + + /** + * Set the remote URL base. + * + * @param $url + * Base of the remote URL, for example: http://example.com + */ + protected function setUrl($url) { + $prefix = self::$REMOTE_PREFIX; + $this->tearDown(); + $this->remoteUrl = $url; + $this->setUp(); + self::$REMOTE_PREFIX = $prefix; + } + + /** + * Reset the remote URL base to the value in 'simpletest_remote_url'. + */ + protected function resetUrl() { + $this->setUrl(variable_get('simpletest_remote_url', FALSE)); + } + +// /** +// * Set url() option 'alias' to TRUE to ensure no path lookup. +// */ +// protected function drupalGet($path, array $options = array(), array $headers = array()) { +// $options['alias'] = TRUE; +// return parent::drupalGet($path, $options, $headers); +// } +// +// /** +// * Set url() option 'alias' to TRUE to ensure no path lookup. +// */ +// protected function drupalPost($path, $edit, $submit, array $options = array(), array $headers = array(), $form_html_id = NULL) { +// $options['alias'] = TRUE; +// return parent::drupalPost($path, $edit, $submit, $options, $headers, $form_html_id); +// } +// +// /** +// * Set url() option 'alias' to TRUE to ensure no path lookup. +// */ +// protected function drupalPostAJAX($path, $edit, $triggering_element, $ajax_path = 'system/ajax', array $options = array(), array $headers = array(), $form_html_id = NULL, $ajax_settings = array()) { +// $options['alias'] = TRUE; +// parent::drupalPostAJAX($path, $edit, $triggering_element, $ajax_path, $options, $headers, $form_html_id, $ajax_settings); +// } + + /** + * Override to ensure not database activity. + */ + protected function refreshVariables() { + // Do nothing. + } + + /** + * Add remote prefix. + */ + public static function randomName($length = 8) { + return self::$REMOTE_PREFIX . parent::randomName($length); + } + + /** + * Add remote prefix. + */ + public static function randomString($length = 8) { + return self::$REMOTE_PREFIX . parent::randomString($length); + } + + /** + * Temporarily revert the global URL variables so verbose links will print. + */ + protected function verbose($message) { + if ($this->remoteUrl) { + foreach (self::$URL_VARIABLES as $variable) { + $GLOBALS[$variable] = $this->originalUrls[$variable]; + } + } + + parent::verbose($message); + + if ($this->remoteUrl) { + foreach (self::$URL_VARIABLES as $variable) { + $GLOBALS[$variable] = $this->remoteUrl; + } + $GLOBALS['base_secure_url'] = str_replace('http://', 'https://', $GLOBALS['base_secure_url']); + } + } +} + /** * Logs verbose message in a text file. * diff --git a/modules/simpletest/files/javascript-1.txt b/modules/simpletest/files/javascript-1.txt index efd44fd..cee8b0e 100644 --- a/modules/simpletest/files/javascript-1.txt +++ b/modules/simpletest/files/javascript-1.txt @@ -1,3 +1,3 @@ diff --git a/modules/simpletest/files/javascript-2.script b/modules/simpletest/files/javascript-2.script index e0206ba..b0a5e33 100644 --- a/modules/simpletest/files/javascript-2.script +++ b/modules/simpletest/files/javascript-2.script @@ -1,3 +1,3 @@ \ No newline at end of file diff --git a/modules/simpletest/monitor/simpletest_monitor.info b/modules/simpletest/monitor/simpletest_monitor.info new file mode 100644 index 0000000..ca25b81 --- /dev/null +++ b/modules/simpletest/monitor/simpletest_monitor.info @@ -0,0 +1,6 @@ + +name = Testing API Monitor +description = Ensure that 2.x style tests are removed when core API is being used. +package = Testing +core = 7.x +files[] = simpletest_monitor.module diff --git a/modules/simpletest/monitor/simpletest_monitor.module b/modules/simpletest/monitor/simpletest_monitor.module new file mode 100644 index 0000000..255e77f --- /dev/null +++ b/modules/simpletest/monitor/simpletest_monitor.module @@ -0,0 +1,36 @@ +name == 'simpletest') { + $api = substr($module->dir, 0, 7) == 'modules' ? 1 : 2; + break; + } + } + + if ($api == 1) { + // Remove 2.x compatible test files. + foreach ($modules as $module) { + if (!empty($module->info['files'])) { + if (!empty($module->info['testing_api']) && $module->info['testing_api'] == '2.x') { + $dir = $module->dir; + foreach ($module->info['files'] as $file) { + if (substr($file, -5) == '.test') { + unset($files["$dir/$file"]); + } + } + } + } + } + } +} diff --git a/modules/simpletest/simpletest.info b/modules/simpletest/simpletest.info index 0e3c630..ec88d7b 100644 --- a/modules/simpletest/simpletest.info +++ b/modules/simpletest/simpletest.info @@ -1,45 +1,10 @@ name = Testing description = Provides a framework for unit and functional testing. -package = Core -version = VERSION +package = Testing core = 7.x files[] = simpletest.test files[] = drupal_web_test_case.php configure = admin/config/development/testing/settings +dependencies[] = simpletest_monitor -; Tests in tests directory. -files[] = tests/actions.test -files[] = tests/ajax.test -files[] = tests/batch.test -files[] = tests/bootstrap.test -files[] = tests/cache.test -files[] = tests/common.test -files[] = tests/database_test.test -files[] = tests/entity_crud_hook_test.test -files[] = tests/entity_query.test -files[] = tests/error.test -files[] = tests/file.test -files[] = tests/filetransfer.test -files[] = tests/form.test -files[] = tests/graph.test -files[] = tests/image.test -files[] = tests/lock.test -files[] = tests/mail.test -files[] = tests/menu.test -files[] = tests/module.test -files[] = tests/password.test -files[] = tests/path.test -files[] = tests/registry.test -files[] = tests/schema.test -files[] = tests/session.test -files[] = tests/theme.test -files[] = tests/unicode.test -files[] = tests/update.test -files[] = tests/xmlrpc.test -files[] = tests/upgrade/upgrade.test -files[] = tests/upgrade/upgrade.comment.test -files[] = tests/upgrade/upgrade.filter.test -files[] = tests/upgrade/upgrade.node.test -files[] = tests/upgrade/upgrade.taxonomy.test -files[] = tests/upgrade/upgrade.upload.test -files[] = tests/upgrade/upgrade.locale.test +testing_api = 2.x diff --git a/modules/simpletest/simpletest.module b/modules/simpletest/simpletest.module index b992fd2..03c0058 100644 --- a/modules/simpletest/simpletest.module +++ b/modules/simpletest/simpletest.module @@ -29,7 +29,7 @@ function simpletest_help($path, $arg) { */ function simpletest_menu() { $items['admin/config/development/testing'] = array( - 'title' => 'Testing', + 'title' => 'Testing 2.x', 'page callback' => 'drupal_get_form', 'page arguments' => array('simpletest_test_form'), 'description' => 'Run tests against Drupal core and your active modules. These tests help assure that your site code is working as designed.', @@ -363,16 +363,27 @@ function simpletest_registry_files_alter(&$files, $modules) { foreach ($modules as $module) { // Only add test files for disabled modules, as enabled modules should // already include any test files they provide. - if (!$module->status) { - $dir = $module->dir; - if (!empty($module->info['files'])) { - foreach ($module->info['files'] as $file) { - if (substr($file, -5) == '.test') { - $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight); + if (!empty($module->info['testing_api']) && $module->info['testing_api'] == '2.x') { + if (!$module->status) { + $dir = $module->dir; + if (!empty($module->info['files'])) { + foreach ($module->info['files'] as $file) { + if (substr($file, -5) == '.test') { + $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight); + } } } } } + else { + // Remove non 2.x compatible test files. + foreach ($module->info['files'] as $file) { + if (substr($file, -5) == '.test') { + $dir = $module->dir; + unset($files["$dir/$file"]); + } + } + } } } diff --git a/modules/simpletest/simpletest.pages.inc b/modules/simpletest/simpletest.pages.inc index 732d641..d10d78f 100644 --- a/modules/simpletest/simpletest.pages.inc +++ b/modules/simpletest/simpletest.pages.inc @@ -195,13 +195,23 @@ function _simpletest_sort_by_title($a, $b) { function simpletest_test_form_submit($form, &$form_state) { // Get list of tests. $tests_list = array(); + $not_found = FALSE; foreach ($form_state['values'] as $class_name => $value) { // Since class_exists() will likely trigger an autoload lookup, // we do the fast check first. if ($value === 1 && class_exists($class_name)) { $tests_list[] = $class_name; } + else { + $not_found = TRUE; + } + } + + if ($not_found) { + drupal_flush_all_caches(); + drupal_set_message(t('One or more of the test classes was not found. The cache has been cleared to correct the issue.'), 'error'); } + if (count($tests_list) > 0 ) { $test_id = simpletest_run_tests($tests_list, 'drupal'); $form_state['redirect'] = 'admin/config/development/testing/results/' . $test_id; @@ -253,7 +263,7 @@ function simpletest_result_form($form, &$form_state, $test_id) { $info = call_user_func(array($group, 'getInfo')); $form['result']['results'][$group] = array( '#type' => 'fieldset', - '#title' => $info['name'], + '#title' => $info['group'] . ': ' . $info['name'], '#description' => $info['description'], '#collapsible' => TRUE, ); @@ -452,6 +462,12 @@ function simpletest_settings_form($form, &$form_state) { '#description' => t('By default SimpleTest will clear the results after they have been viewed on the results page, but in some cases it may be useful to leave the results in the database. The results can then be viewed at admin/config/development/testing/[test_id]. The test ID can be found in the database, simpletest table, or kept track of when viewing the results the first time. Additionally, some modules may provide more analysis or features that require this setting to be disabled.'), '#default_value' => variable_get('simpletest_clear_results', TRUE), ); + $form['general']['simpletest_remove_tables'] = array( + '#type' => 'checkbox', + '#title' => t('Remove prefixed tables after each complete test suite run'), + '#description' => t('By default SimpleTest will remove the prefixed tables created during testing, but in some cases it may be useful to leave the tables in the database.'), + '#default_value' => variable_get('simpletest_remove_tables', TRUE), + ); $form['general']['simpletest_verbose'] = array( '#type' => 'checkbox', '#title' => t('Provide verbose information when running tests'), @@ -489,6 +505,19 @@ function simpletest_settings_form($form, &$form_state) { '#title' => t('Password'), '#default_value' => variable_get('simpletest_httpauth_password', ''), ); + $form['remote'] = array( + '#type' => 'fieldset', + '#title' => t('Remote'), + '#description' => t('Settings related to remote testing.'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + ); + $form['remote']['simpletest_remote_url'] = array( + '#type' => 'textfield', + '#title' => t('URL'), + '#description' => t('Remote URL to perform testing against, leave blank for local url.'), + '#default_value' => variable_get('simpletest_remote_url', ''), + ); return system_settings_form($form); } diff --git a/modules/simpletest/simpletest.test b/modules/simpletest/simpletest.test index f516364..081d4d3 100644 --- a/modules/simpletest/simpletest.test +++ b/modules/simpletest/simpletest.test @@ -6,6 +6,7 @@ */ class SimpleTestFunctionalTest extends DrupalWebTestCase { + /** * The results array that has been parsed by getTestResults(). */ @@ -19,18 +20,15 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { public static function getInfo() { return array( - 'name' => 'SimpleTest functionality', - 'description' => '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' => 'SimpleTest' + 'name' => 'Web runner', + 'description' => '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' => 'SimpleTest', ); } - function setUp() { + protected function setUp() { if (!$this->inCURL()) { - parent::setUp('simpletest'); + parent::setUp(array('simpletest')); // Create and login user $admin_user = $this->drupalCreateUser(array('administer unit tests')); @@ -44,7 +42,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { /** * Test the internal browsers functionality. */ - function testInternalBrowser() { + protected function testInternalBrowser() { global $conf; if (!$this->inCURL()) { $this->drupalGet('node'); @@ -122,7 +120,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { * Make sure that tests selected through the web interface are run and * that the results are displayed correctly. */ - function testWebTestRunner() { + protected function testWebTestRunner() { $this->pass = t('SimpleTest pass.'); $this->fail = t('SimpleTest fail.'); $this->valid_permission = 'access content'; @@ -157,7 +155,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { /** * Test to be run and the results confirmed. */ - function stubTest() { + protected function stubTest() { $this->pass($this->pass); $this->fail($this->fail); @@ -181,14 +179,14 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { /** * Assert nothing. */ - function assertNothing() { + protected function assertNothing() { $this->pass("This is nothing."); } /** * Confirm that the stub test produced the desired results. */ - function confirmStubTestResults() { + protected function confirmStubTestResults() { $this->assertAssertion($this->pass, 'Other', 'Pass', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()'); $this->assertAssertion($this->fail, 'Other', 'Fail', 'simpletest.test', 'SimpleTestFunctionalTest->stubTest()'); @@ -217,7 +215,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { /** * Fetch the test id from the test results. */ - function getTestIdFromResults() { + protected function getTestIdFromResults() { foreach ($this->childTestResults['assertions'] as $assertion) { if (preg_match('@^Test ID is ([0-9]*)\.$@', $assertion['message'], $matches)) { return $matches[1]; @@ -237,7 +235,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { * @param string $functuion Function where the assertion originated. * @return Assertion result. */ - function assertAssertion($message, $type, $status, $file, $function) { + protected function assertAssertion($message, $type, $status, $file, $function) { $message = trim(strip_tags($message)); $found = FALSE; foreach ($this->childTestResults['assertions'] as $assertion) { @@ -256,7 +254,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { /** * Get the results from a test and store them in the class array $results. */ - function getTestResults() { + protected function getTestResults() { $results = array(); if ($this->parse()) { if ($fieldset = $this->getResultFieldSet()) { @@ -285,11 +283,11 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { /** * Get the fieldset containing the results for group this test is in. */ - function getResultFieldSet() { + protected function getResultFieldSet() { $fieldsets = $this->xpath('//fieldset'); $info = $this->getInfo(); foreach ($fieldsets as $fieldset) { - if ($this->asText($fieldset->legend) == $info['name']) { + if ($this->asText($fieldset->legend) == $info['group'] . ': ' . $info['name']) { return $fieldset; } } @@ -304,7 +302,7 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { * @return * Extracted text. */ - function asText(SimpleXMLElement $element) { + protected function asText(SimpleXMLElement $element) { if (!is_object($element)) { return $this->fail('The element is not an element.'); } @@ -322,11 +320,12 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase { /** * Test internal testing framework browser. */ -class SimpleTestBrowserTestCase extends DrupalWebTestCase { +class SimpleTestURLTestCase extends DrupalWebTestCase { + public static function getInfo() { return array( - 'name' => 'SimpleTest browser', - 'description' => 'Test the internal browser of the testing framework.', + 'name' => 'URL handling', + 'description' => 'Test the URL handling in the testing framework.', 'group' => 'SimpleTest', ); } @@ -339,7 +338,7 @@ class SimpleTestBrowserTestCase extends DrupalWebTestCase { /** * Test DrupalWebTestCase::getAbsoluteUrl(). */ - function testGetAbsoluteUrl() { + protected function testGetAbsoluteUrl() { // Testbed runs with Clean URLs disabled, so disable it here. variable_set('clean_url', 0); $url = 'user/login'; @@ -384,12 +383,10 @@ EOF; } class SimpleTestMailCaptureTestCase extends DrupalWebTestCase { - /** - * Implement getInfo(). - */ + public static function getInfo() { return array( - 'name' => 'SimpleTest e-mail capturing', + 'name' => 'E-mail capturing', 'description' => 'Test the SimpleTest e-mail capturing logic, the assertMail assertion and the drupalGetMails function.', 'group' => 'SimpleTest', ); @@ -398,7 +395,7 @@ class SimpleTestMailCaptureTestCase extends DrupalWebTestCase { /** * Test to see if the wrapper function is executed correctly. */ - function testMailSend() { + protected function testMailSend() { // Create an e-mail. $subject = $this->randomString(64); $body = $this->randomString(128); @@ -485,9 +482,10 @@ class SimpleTestFolderTestCase extends DrupalWebTestCase { * Test required modules for tests. */ class SimpleTestMissingDependentModuleUnitTest extends DrupalUnitTestCase { + public static function getInfo() { return array( - 'name' => 'Testing dependent module test', + 'name' => 'Dependent module test', 'description' => 'This test should not load since it requires a module that is not found.', 'group' => 'SimpleTest', 'dependencies' => array('simpletest_missing_module'), @@ -497,7 +495,7 @@ class SimpleTestMissingDependentModuleUnitTest extends DrupalUnitTestCase { /** * Ensure that this test will not be loaded despite its dependency. */ - function testFail() { + protected function testFail() { $this->fail(t('Running test with missing required module.')); } }