Example #1
0
 protected function testList(DrupalStyle $io, $group)
 {
     $testingGroups = $this->test_discovery->getTestClasses(null);
     if (empty($group)) {
         $tableHeader = [$this->trans('commands.test.debug.messages.group')];
     } else {
         $tableHeader = [$this->trans('commands.test.debug.messages.class'), $this->trans('commands.test.debug.messages.type')];
         $io->writeln(sprintf('%s: %s', $this->trans('commands.test.debug.messages.group'), $group));
     }
     $tableRows = [];
     foreach ($testingGroups as $testing_group => $tests) {
         if (empty($group)) {
             $tableRows[] = [$testing_group];
             continue;
         }
         if (!empty($group) && $group != $testing_group) {
             continue;
         }
         foreach ($tests as $test) {
             if (is_subclass_of($test['name'], 'PHPUnit_Framework_TestCase')) {
                 $test['type'] = 'phpunit';
             } else {
                 $test['type'] = 'simpletest';
             }
             $tableRows[] = [$test['name'], $test['type']];
         }
     }
     $io->table($tableHeader, $tableRows, 'compact');
     if ($group) {
         $io->success(sprintf($this->trans('commands.test.debug.messages.success-group'), $group));
     } else {
         $io->success($this->trans('commands.test.debug.messages.success-groups'));
     }
 }
    /**
     * @covers ::getTestInfo
     * @expectedException \Drupal\simpletest\Exception\MissingSummaryLineException
     * @expectedExceptionMessage Missing PHPDoc summary line in Drupal\field\Tests\BulkDeleteTest
     */
    public function testTestInfoParserMissingSummary()
    {
        $classname = 'Drupal\\field\\Tests\\BulkDeleteTest';
        $doc_comment = <<<EOT
/**
 * @group field
 */
EOT;
        \Drupal\simpletest\TestDiscovery::getTestInfo($classname, $doc_comment);
    }
Example #3
0
    /**
     * @covers ::getTestInfo
     */
    public function testTestInfoParserMissingSummary()
    {
        $classname = 'Drupal\\field\\Tests\\BulkDeleteTest';
        $doc_comment = <<<EOT
/**
 * @group field
 */
EOT;
        $info = \Drupal\simpletest\TestDiscovery::getTestInfo($classname, $doc_comment);
        $this->assertEmpty($info['description']);
    }
Example #4
0
 /**
  * Find and add tests to the suite for core and any extensions.
  *
  * @param string $root
  *   Path to the root of the Drupal installation.
  * @param string $suite_namespace
  *   SubNamespace used to separate test suite. Examples: Unit, Functional.
  */
 protected function addTestsBySuiteNamespace($root, $suite_namespace)
 {
     // Core's tests are in the namespace Drupal\${suite_namespace}Tests\ and are
     // always inside of core/tests/Drupal/${suite_namespace}Tests. The exception
     // to this is Unit tests for historical reasons.
     if ($suite_namespace == 'Unit') {
         $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\Tests\\", "{$root}/core/tests/Drupal/Tests"));
     } else {
         $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\{$suite_namespace}Tests\\", "{$root}/core/tests/Drupal/{$suite_namespace}Tests"));
     }
     // Extensions' tests will always be in the namespace
     // Drupal\Tests\$extension_name\$suite_namespace\ and be in the
     // $extension_path/tests/src/$suite_namespace directory. Not all extensions
     // will have all kinds of tests.
     foreach ($this->findExtensionDirectories($root) as $extension_name => $dir) {
         $test_path = "{$dir}/tests/src/{$suite_namespace}";
         if (is_dir($test_path)) {
             $this->addTestFiles(TestDiscovery::scanDirectory("Drupal\\Tests\\{$extension_name}\\{$suite_namespace}\\", $test_path));
         }
     }
 }
Example #5
0
 /**
  * @covers ::getPhpunitTestSuite
  * @dataProvider providerTestGetPhpunitTestSuite
  */
 public function testGetPhpunitTestSuite($classname, $expected)
 {
     $this->assertEquals($expected, TestDiscovery::getPhpunitTestSuite($classname));
 }
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, array &$form_state, $test_id = NULL)
 {
     $this->buildStatusImageMap();
     // Make sure there are test results to display and a re-run is not being
     // performed.
     $results = array();
     if (is_numeric($test_id) && !($results = $this->getResults($test_id))) {
         drupal_set_message($this->t('No test results to display.'), 'error');
         return new RedirectResponse(url('admin/config/development/testing', array('absolute' => TRUE)));
     }
     // Load all classes and include CSS.
     $form['#attached']['css'][] = drupal_get_path('module', 'simpletest') . '/css/simpletest.module.css';
     // Keep track of which test cases passed or failed.
     $filter = array('pass' => array(), 'fail' => array());
     // Summary result widget.
     $form['result'] = array('#type' => 'fieldset', '#title' => $this->t('Results'));
     $form['result']['summary'] = $summary = array('#theme' => 'simpletest_result_summary', '#pass' => 0, '#fail' => 0, '#exception' => 0, '#debug' => 0);
     simpletest_classloader_register();
     // Cycle through each test group.
     $header = array($this->t('Message'), $this->t('Group'), $this->t('Filename'), $this->t('Line'), $this->t('Function'), array('colspan' => 2, 'data' => $this->t('Status')));
     $form['result']['results'] = array();
     foreach ($results as $group => $assertions) {
         // Create group details with summary information.
         $info = TestDiscovery::getTestInfo(new \ReflectionClass($group));
         $form['result']['results'][$group] = array('#type' => 'details', '#title' => $info['name'], '#open' => TRUE, '#description' => $info['description']);
         $form['result']['results'][$group]['summary'] = $summary;
         $group_summary =& $form['result']['results'][$group]['summary'];
         // Create table of assertions for the group.
         $rows = array();
         foreach ($assertions as $assertion) {
             $row = array();
             // Assertion messages are in code, so we assume they are safe.
             $row[] = SafeMarkup::set($assertion->message);
             $row[] = $assertion->message_group;
             $row[] = drupal_basename($assertion->file);
             $row[] = $assertion->line;
             $row[] = $assertion->function;
             $row[] = $this->statusImageMap[$assertion->status];
             $class = 'simpletest-' . $assertion->status;
             if ($assertion->message_group == 'Debug') {
                 $class = 'simpletest-debug';
             }
             $rows[] = array('data' => $row, 'class' => array($class));
             $group_summary['#' . $assertion->status]++;
             $form['result']['summary']['#' . $assertion->status]++;
         }
         $form['result']['results'][$group]['table'] = array('#type' => 'table', '#header' => $header, '#rows' => $rows);
         // Set summary information.
         $group_summary['#ok'] = $group_summary['#fail'] + $group_summary['#exception'] == 0;
         $form['result']['results'][$group]['#open'] = !$group_summary['#ok'];
         // Store test group (class) as for use in filter.
         $filter[$group_summary['#ok'] ? 'pass' : 'fail'][] = $group;
     }
     // Overall summary status.
     $form['result']['summary']['#ok'] = $form['result']['summary']['#fail'] + $form['result']['summary']['#exception'] == 0;
     // Actions.
     $form['#action'] = url('admin/config/development/testing/results/re-run');
     $form['action'] = array('#type' => 'fieldset', '#title' => $this->t('Actions'), '#attributes' => array('class' => array('container-inline')), '#weight' => -11);
     $form['action']['filter'] = array('#type' => 'select', '#title' => 'Filter', '#options' => array('all' => $this->t('All (@count)', array('@count' => count($filter['pass']) + count($filter['fail']))), 'pass' => $this->t('Pass (@count)', array('@count' => count($filter['pass']))), 'fail' => $this->t('Fail (@count)', array('@count' => count($filter['fail'])))));
     $form['action']['filter']['#default_value'] = $filter['fail'] ? 'fail' : 'all';
     // Categorized test classes for to be used with selected filter value.
     $form['action']['filter_pass'] = array('#type' => 'hidden', '#default_value' => implode(',', $filter['pass']));
     $form['action']['filter_fail'] = array('#type' => 'hidden', '#default_value' => implode(',', $filter['fail']));
     $form['action']['op'] = array('#type' => 'submit', '#value' => $this->t('Run tests'));
     $form['action']['return'] = array('#type' => 'link', '#title' => $this->t('Return to list'), '#href' => 'admin/config/development/testing');
     if (is_numeric($test_id)) {
         simpletest_clean_results_table($test_id);
     }
     return $form;
 }
 /**
  * Adds the result form to a $form.
  *
  * This is a static method so that run-tests.sh can use it to generate a
  * results page completely external to Drupal. This is why the UI strings are
  * not wrapped in t().
  *
  * @param array $form
  *   The form to attach the results to.
  * @param array $test_results
  *   The simpletest results.
  *
  * @return array
  *   A list of tests the passed and failed. The array has two keys, 'pass' and
  *   'fail'. Each contains a list of test classes.
  *
  * @see simpletest_script_open_browser()
  * @see run-tests.sh
  */
 public static function addResultForm(array &$form, array $results)
 {
     // Transform the test results to be grouped by test class.
     $test_results = array();
     foreach ($results as $result) {
         if (!isset($test_results[$result->test_class])) {
             $test_results[$result->test_class] = array();
         }
         $test_results[$result->test_class][] = $result;
     }
     $image_status_map = static::buildStatusImageMap();
     // Keep track of which test cases passed or failed.
     $filter = array('pass' => array(), 'fail' => array());
     // Summary result widget.
     $form['result'] = array('#type' => 'fieldset', '#title' => 'Results', '#attributes' => array());
     $form['result']['summary'] = $summary = array('#theme' => 'simpletest_result_summary', '#pass' => 0, '#fail' => 0, '#exception' => 0, '#debug' => 0);
     \Drupal::service('test_discovery')->registerTestNamespaces();
     // Cycle through each test group.
     $header = array('Message', 'Group', 'Filename', 'Line', 'Function', array('colspan' => 2, 'data' => 'Status'));
     $form['result']['results'] = array();
     foreach ($test_results as $group => $assertions) {
         // Create group details with summary information.
         $info = TestDiscovery::getTestInfo($group);
         $form['result']['results'][$group] = array('#type' => 'details', '#title' => $info['name'], '#open' => TRUE, '#description' => $info['description']);
         $form['result']['results'][$group]['summary'] = $summary;
         $group_summary =& $form['result']['results'][$group]['summary'];
         // Create table of assertions for the group.
         $rows = array();
         foreach ($assertions as $assertion) {
             $row = array();
             $row[] = SafeMarkup::checkAdminXss($assertion->message);
             $row[] = $assertion->message_group;
             $row[] = \Drupal::service('file_system')->basename($assertion->file);
             $row[] = $assertion->line;
             $row[] = $assertion->function;
             $row[] = ['data' => $image_status_map[$assertion->status]];
             $class = 'simpletest-' . $assertion->status;
             if ($assertion->message_group == 'Debug') {
                 $class = 'simpletest-debug';
             }
             $rows[] = array('data' => $row, 'class' => array($class));
             $group_summary['#' . $assertion->status]++;
             $form['result']['summary']['#' . $assertion->status]++;
         }
         $form['result']['results'][$group]['table'] = array('#type' => 'table', '#header' => $header, '#rows' => $rows);
         // Set summary information.
         $group_summary['#ok'] = $group_summary['#fail'] + $group_summary['#exception'] == 0;
         $form['result']['results'][$group]['#open'] = !$group_summary['#ok'];
         // Store test group (class) as for use in filter.
         $filter[$group_summary['#ok'] ? 'pass' : 'fail'][] = $group;
     }
     // Overall summary status.
     $form['result']['summary']['#ok'] = $form['result']['summary']['#fail'] + $form['result']['summary']['#exception'] == 0;
     return $filter;
 }
Example #8
0
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $io = new DrupalStyle($input, $output);
     //Registers namespaces for disabled modules.
     $this->test_discovery->registerTestNamespaces();
     $testClass = $input->getArgument('test-class');
     $testMethods = $input->getArgument('test-methods');
     $url = $input->getOption('url');
     if (!$url) {
         $io->error($this->trans('commands.test.run.messages.url-required'));
         return null;
     }
     $this->setEnvironment($url);
     // Create simpletest test id
     $testId = db_insert('simpletest_test_id')->useDefaults(['test_id'])->execute();
     if (is_subclass_of($testClass, 'PHPUnit_Framework_TestCase')) {
         $io->info($this->trans('commands.test.run.messages.phpunit-pending'));
         return null;
     } else {
         if (!class_exists($testClass)) {
             $io->error(sprintf($this->trans('commands.test.run.messages.invalid-class'), $testClass));
             return 1;
         }
         $test = new $testClass($testId);
         $io->info($this->trans('commands.test.run.messages.starting-test'));
         Timer::start('run-tests');
         $test->run($testMethods);
         $end = Timer::stop('run-tests');
         $io->simple($this->trans('commands.test.run.messages.test-duration') . ': ' . $this->dateFormatter->formatInterval($end['time'] / 1000));
         $io->simple($this->trans('commands.test.run.messages.test-pass') . ': ' . $test->results['#pass']);
         $io->commentBlock($this->trans('commands.test.run.messages.test-fail') . ': ' . $test->results['#fail']);
         $io->commentBlock($this->trans('commands.test.run.messages.test-exception') . ': ' . $test->results['#exception']);
         $io->simple($this->trans('commands.test.run.messages.test-debug') . ': ' . $test->results['#debug']);
         $this->moduleHandler->invokeAll('test_finished', [$test->results]);
         $io->newLine();
         $io->info($this->trans('commands.test.run.messages.test-summary'));
         $io->newLine();
         $currentClass = null;
         $currentGroup = null;
         $currentStatus = null;
         $messages = $this->simpletestScriptLoadMessagesByTestIds([$testId]);
         foreach ($messages as $message) {
             if ($currentClass === null || $currentClass != $message->test_class) {
                 $currentClass = $message->test_class;
                 $io->comment($message->test_class);
             }
             if ($currentGroup === null || $currentGroup != $message->message_group) {
                 $currentGroup = $message->message_group;
             }
             if ($currentStatus === null || $currentStatus != $message->status) {
                 $currentStatus = $message->status;
                 if ($message->status == 'fail') {
                     $io->error($this->trans('commands.test.run.messages.group') . ':' . $message->message_group . ' ' . $this->trans('commands.test.run.messages.status') . ':' . $message->status);
                     $io->newLine();
                 } else {
                     $io->info($this->trans('commands.test.run.messages.group') . ':' . $message->message_group . ' ' . $this->trans('commands.test.run.messages.status') . ':' . $message->status);
                     $io->newLine();
                 }
             }
             $io->simple($this->trans('commands.test.run.messages.file') . ': ' . str_replace($this->appRoot, '', $message->file));
             $io->simple($this->trans('commands.test.run.messages.method') . ': ' . $message->function);
             $io->simple($this->trans('commands.test.run.messages.line') . ': ' . $message->line);
             $io->simple($this->trans('commands.test.run.messages.message') . ': ' . $message->message);
             $io->newLine();
         }
         return null;
     }
 }