Skip to content
Snippets Groups Projects
Verified Commit 76f37294 authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #2641632 by Mile23, kim.pepper, Munavijayalakshmi, dawehner, klausi,...

Issue #2641632 by Mile23, kim.pepper, Munavijayalakshmi, dawehner, klausi, joachim, xjm: Refactor simpletest's *_phpunit_*() (and junit) functions etc. to a class, deprecate
parent 11c62acb
No related branches found
No related tags found
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
Showing
with 870 additions and 212 deletions
<?php
namespace Drupal\Core\Test;
/**
* Converts JUnit XML to Drupal's {simpletest} schema.
*
* This is mainly for converting PHPUnit test results.
*
* This class is @internal and not considered to be API.
*/
class JUnitConverter {
/**
* Converts PHPUnit's JUnit XML output file to {simpletest} schema.
*
* @param int $test_id
* The current test ID.
* @param string $phpunit_xml_file
* Path to the PHPUnit XML file.
*
* @return array[]
* The results as array of rows in a format that can be inserted into the
* {simpletest} table of the results database.
*
* @internal
*/
public static function xmlToRows($test_id, $phpunit_xml_file) {
$contents = @file_get_contents($phpunit_xml_file);
if (!$contents) {
return [];
}
return static::xmlElementToRows($test_id, new \SimpleXMLElement($contents));
}
/**
* Parse test cases from XML to {simpletest} schema.
*
* @param int $test_id
* The current test ID.
* @param \SimpleXMLElement $element
* The XML data from the JUnit file.
*
* @return array[]
* The results as array of rows in a format that can be inserted into the
* {simpletest} table of the results database.
*
* @internal
*/
public static function xmlElementToRows($test_id, \SimpleXMLElement $element) {
$records = [];
$test_cases = static::findTestCases($element);
foreach ($test_cases as $test_case) {
$records[] = static::convertTestCaseToSimpletestRow($test_id, $test_case);
}
return $records;
}
/**
* Finds all test cases recursively from a test suite list.
*
* @param \SimpleXMLElement $element
* The PHPUnit xml to search for test cases.
* @param \SimpleXMLElement $parent
* (Optional) The parent of the current element. Defaults to NULL.
*
* @return array
* A list of all test cases.
*
* @internal
*/
public static function findTestCases(\SimpleXMLElement $element, \SimpleXMLElement $parent = NULL) {
if (!isset($parent)) {
$parent = $element;
}
if ($element->getName() === 'testcase' && (int) $parent->attributes()->tests > 0) {
// Add the class attribute if the test case does not have one. This is the
// case for tests using a data provider. The name of the parent testsuite
// will be in the format class::method.
if (!$element->attributes()->class) {
$name = explode('::', $parent->attributes()->name, 2);
$element->addAttribute('class', $name[0]);
}
return [$element];
}
$test_cases = [];
foreach ($element as $child) {
$file = (string) $parent->attributes()->file;
if ($file && !$child->attributes()->file) {
$child->addAttribute('file', $file);
}
$test_cases = array_merge($test_cases, static::findTestCases($child, $element));
}
return $test_cases;
}
/**
* Converts a PHPUnit test case result to a {simpletest} result row.
*
* @param int $test_id
* The current test ID.
* @param \SimpleXMLElement $test_case
* The PHPUnit test case represented as XML element.
*
* @return array
* An array containing the {simpletest} result row.
*
* @internal
*/
public static function convertTestCaseToSimpletestRow($test_id, \SimpleXMLElement $test_case) {
$message = '';
$pass = TRUE;
if ($test_case->failure) {
$lines = explode("\n", $test_case->failure);
$message = $lines[2];
$pass = FALSE;
}
if ($test_case->error) {
$message = $test_case->error;
$pass = FALSE;
}
$attributes = $test_case->attributes();
$record = [
'test_id' => $test_id,
'test_class' => (string) $attributes->class,
'status' => $pass ? 'pass' : 'fail',
'message' => $message,
'message_group' => 'Other',
'function' => $attributes->class . '->' . $attributes->name . '()',
'line' => (int) $attributes->line ?: 0,
'file' => (string) $attributes->file,
];
return $record;
}
}
<?php
namespace Drupal\Core\Test;
use Drupal\Core\Database\Database;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Tests\Listeners\SimpletestUiPrinter;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Process\PhpExecutableFinder;
/**
* Run PHPUnit-based tests.
*
* This class runs PHPUnit-based tests and converts their JUnit results to a
* format that can be stored in the {simpletest} database schema.
*
* This class is @internal and not considered to be API.
*
* @code
* $runner = PhpUnitTestRunner::create(\Drupal::getContainer());
* $results = $runner->runTests($test_id, $test_list['phpunit']);
* @endcode
*/
class PhpUnitTestRunner implements ContainerInjectionInterface {
/**
* Path to the working directory.
*
* JUnit log files will be stored in this directory.
*
* @var string
*/
protected $workingDirectory;
/**
* Path to the application root.
*
* @var string
*/
protected $appRoot;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
(string) $container->get('app.root'),
(string) $container->get('file_system')->realpath('public://simpletest')
);
}
/**
* Constructs a test runner.
*
* @param string $app_root
* Path to the application root.
* @param string $working_directory
* Path to the working directory. JUnit log files will be stored in this
* directory.
*/
public function __construct($app_root, $working_directory) {
$this->appRoot = $app_root;
$this->workingDirectory = $working_directory;
}
/**
* Returns the path to use for PHPUnit's --log-junit option.
*
* @param int $test_id
* The current test ID.
*
* @return string
* Path to the PHPUnit XML file to use for the current $test_id.
*
* @internal
*/
public function xmlLogFilePath($test_id) {
return $this->workingDirectory . '/phpunit-' . $test_id . '.xml';
}
/**
* Returns the command to run PHPUnit.
*
* @return string
* The command that can be run through exec().
*
* @internal
*/
public function phpUnitCommand() {
// Load the actual autoloader being used and determine its filename using
// reflection. We can determine the vendor directory based on that filename.
$autoloader = require $this->appRoot . '/autoload.php';
$reflector = new \ReflectionClass($autoloader);
$vendor_dir = dirname(dirname($reflector->getFileName()));
// The file in Composer's bin dir is a *nix link, which does not work when
// extracted from a tarball and generally not on Windows.
$command = $vendor_dir . '/phpunit/phpunit/phpunit';
if (substr(PHP_OS, 0, 3) == 'WIN') {
// On Windows it is necessary to run the script using the PHP executable.
$php_executable_finder = new PhpExecutableFinder();
$php = $php_executable_finder->find();
$command = $php . ' -f ' . escapeshellarg($command) . ' --';
}
return $command;
}
/**
* Executes the PHPUnit command.
*
* @param string[] $unescaped_test_classnames
* An array of test class names, including full namespaces, to be passed as
* a regular expression to PHPUnit's --filter option.
* @param string $phpunit_file
* A filepath to use for PHPUnit's --log-junit option.
* @param int $status
* (optional) The exit status code of the PHPUnit process will be assigned
* to this variable.
* @param string[] $output
* (optional) The output by running the phpunit command. If provided, this
* array will contain the lines output by the command.
*
* @return string
* The results as returned by exec().
*
* @internal
*/
public function runCommand(array $unescaped_test_classnames, $phpunit_file, &$status = NULL, &$output = NULL) {
global $base_url;
// Setup an environment variable containing the database connection so that
// functional tests can connect to the database.
putenv('SIMPLETEST_DB=' . Database::getConnectionInfoAsUrl());
// Setup an environment variable containing the base URL, if it is available.
// This allows functional tests to browse the site under test. When running
// tests via CLI, core/phpunit.xml.dist or core/scripts/run-tests.sh can set
// this variable.
if ($base_url) {
putenv('SIMPLETEST_BASE_URL=' . $base_url);
putenv('BROWSERTEST_OUTPUT_DIRECTORY=' . $this->workingDirectory);
}
$phpunit_bin = $this->phpUnitCommand();
$command = [
$phpunit_bin,
'--log-junit',
escapeshellarg($phpunit_file),
'--printer',
escapeshellarg(SimpletestUiPrinter::class),
];
// Optimized for running a single test.
if (count($unescaped_test_classnames) == 1) {
$class = new \ReflectionClass($unescaped_test_classnames[0]);
$command[] = escapeshellarg($class->getFileName());
}
else {
// Double escape namespaces so they'll work in a regexp.
$escaped_test_classnames = array_map(function ($class) {
return addslashes($class);
}, $unescaped_test_classnames);
$filter_string = implode("|", $escaped_test_classnames);
$command = array_merge($command, [
'--filter',
escapeshellarg($filter_string),
]);
}
// Need to change directories before running the command so that we can use
// relative paths in the configuration file's exclusions.
$old_cwd = getcwd();
chdir($this->appRoot . "/core");
// exec in a subshell so that the environment is isolated when running tests
// via the simpletest UI.
$ret = exec(implode(" ", $command), $output, $status);
chdir($old_cwd);
putenv('SIMPLETEST_DB=');
if ($base_url) {
putenv('SIMPLETEST_BASE_URL=');
putenv('BROWSERTEST_OUTPUT_DIRECTORY=');
}
return $ret;
}
/**
* Executes PHPUnit tests and returns the results of the run.
*
* @param int $test_id
* The current test ID.
* @param string[] $unescaped_test_classnames
* An array of test class names, including full namespaces, to be passed as
* a regular expression to PHPUnit's --filter option.
* @param int $status
* (optional) The exit status code of the PHPUnit process will be assigned
* to this variable.
*
* @return array
* The parsed results of PHPUnit's JUnit XML output, in the format of
* {simpletest}'s schema.
*
* @internal
*/
public function runTests($test_id, array $unescaped_test_classnames, &$status = NULL) {
$phpunit_file = $this->xmlLogFilePath($test_id);
// Store ouptut from our test run.
$output = [];
$this->runCommand($unescaped_test_classnames, $phpunit_file, $status, $output);
if ($status == TestStatus::PASS) {
return JUnitConverter::xmlToRows($test_id, $phpunit_file);
}
return [
[
'test_id' => $test_id,
'test_class' => implode(",", $unescaped_test_classnames),
'status' => TestStatus::label($status),
'message' => 'PHPunit Test failed to complete; Error: ' . implode("\n", $output),
'message_group' => 'Other',
'function' => implode(",", $unescaped_test_classnames),
'line' => '0',
'file' => $phpunit_file,
],
];
}
/**
* Tallies test results per test class.
*
* @param string[][] $results
* Array of results in the {simpletest} schema. Can be the return value of
* PhpUnitTestRunner::runTests().
*
* @return int[][]
* Array of status tallies, keyed by test class name and status type.
*
* @internal
*/
public function summarizeResults(array $results) {
$summaries = [];
foreach ($results as $result) {
if (!isset($summaries[$result['test_class']])) {
$summaries[$result['test_class']] = [
'#pass' => 0,
'#fail' => 0,
'#exception' => 0,
'#debug' => 0,
];
}
switch ($result['status']) {
case 'pass':
$summaries[$result['test_class']]['#pass']++;
break;
case 'fail':
$summaries[$result['test_class']]['#fail']++;
break;
case 'exception':
$summaries[$result['test_class']]['#exception']++;
break;
case 'debug':
$summaries[$result['test_class']]['#debug']++;
break;
}
}
return $summaries;
}
}
...@@ -5,18 +5,17 @@ ...@@ -5,18 +5,17 @@
* Provides testing functionality. * Provides testing functionality.
*/ */
use Drupal\Core\Url;
use Drupal\Core\Asset\AttachedAssetsInterface; use Drupal\Core\Asset\AttachedAssetsInterface;
use Drupal\Core\Database\Database; use Drupal\Core\Database\Database;
use Drupal\Core\File\Exception\FileException; use Drupal\Core\File\Exception\FileException;
use Drupal\Core\Render\Element; use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Test\JUnitConverter;
use Drupal\Core\Test\PhpUnitTestRunner;
use Drupal\Core\Test\TestDatabase; use Drupal\Core\Test\TestDatabase;
use Drupal\Core\Url;
use Drupal\simpletest\TestDiscovery; use Drupal\simpletest\TestDiscovery;
use Drupal\Tests\Listeners\SimpletestUiPrinter;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\PhpExecutableFinder;
use Drupal\Core\Test\TestStatus;
/** /**
* Implements hook_help(). * Implements hook_help().
...@@ -119,8 +118,9 @@ function _simpletest_format_summary_line($summary) { ...@@ -119,8 +118,9 @@ function _simpletest_format_summary_line($summary) {
/** /**
* Runs tests. * Runs tests.
* *
* @param $test_list * @param array[] $test_list
* List of tests to run. * List of tests to run. The top level is keyed by type of test, either
* 'simpletest' or 'phpunit'. Under that is an array of class names to run.
* *
* @return string * @return string
* The test ID. * The test ID.
...@@ -187,28 +187,16 @@ function simpletest_run_tests($test_list) { ...@@ -187,28 +187,16 @@ function simpletest_run_tests($test_list) {
* @return array * @return array
* The parsed results of PHPUnit's JUnit XML output, in the format of * The parsed results of PHPUnit's JUnit XML output, in the format of
* {simpletest}'s schema. * {simpletest}'s schema.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Test\PhpUnitTestRunner::runTests() instead.
*
* @see https://www.drupal.org/node/2948547
*/ */
function simpletest_run_phpunit_tests($test_id, array $unescaped_test_classnames, &$status = NULL) { function simpletest_run_phpunit_tests($test_id, array $unescaped_test_classnames, &$status = NULL) {
$phpunit_file = simpletest_phpunit_xml_filepath($test_id); $runner = PhpUnitTestRunner::create(\Drupal::getContainer());
simpletest_phpunit_run_command($unescaped_test_classnames, $phpunit_file, $status, $output); @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::runTests() instead. See https://www.drupal.org/node/2948547', E_USER_DEPRECATED);
return $runner->runTests($test_id, $unescaped_test_classnames, $status);
$rows = [];
if ($status == TestStatus::PASS) {
$rows = simpletest_phpunit_xml_to_rows($test_id, $phpunit_file);
}
else {
$rows[] = [
'test_id' => $test_id,
'test_class' => implode(",", $unescaped_test_classnames),
'status' => TestStatus::label($status),
'message' => 'PHPunit Test failed to complete; Error: ' . implode("\n", $output),
'message_group' => 'Other',
'function' => implode(",", $unescaped_test_classnames),
'line' => '0',
'file' => $phpunit_file,
];
}
return $rows;
} }
/** /**
...@@ -239,38 +227,16 @@ function simpletest_process_phpunit_results($phpunit_results) { ...@@ -239,38 +227,16 @@ function simpletest_process_phpunit_results($phpunit_results) {
* *
* @return array * @return array
* The test result summary. A row per test class. * The test result summary. A row per test class.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Test\PhpUnitTestRunner::summarizeResults() instead.
*
* @see https://www.drupal.org/node/2948547
*/ */
function simpletest_summarize_phpunit_result($results) { function simpletest_summarize_phpunit_result($results) {
$summaries = []; $runner = PhpUnitTestRunner::create(\Drupal::getContainer());
foreach ($results as $result) { @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::summarizeResults() instead. See https://www.drupal.org/node/2948547', E_USER_DEPRECATED);
if (!isset($summaries[$result['test_class']])) { return $runner->summarizeResults($results);
$summaries[$result['test_class']] = [
'#pass' => 0,
'#fail' => 0,
'#exception' => 0,
'#debug' => 0,
];
}
switch ($result['status']) {
case 'pass':
$summaries[$result['test_class']]['#pass']++;
break;
case 'fail':
$summaries[$result['test_class']]['#fail']++;
break;
case 'exception':
$summaries[$result['test_class']]['#exception']++;
break;
case 'debug':
$summaries[$result['test_class']]['#debug']++;
break;
}
}
return $summaries;
} }
/** /**
...@@ -281,9 +247,16 @@ function simpletest_summarize_phpunit_result($results) { ...@@ -281,9 +247,16 @@ function simpletest_summarize_phpunit_result($results) {
* *
* @return string * @return string
* Path to the PHPUnit XML file to use for the current $test_id. * Path to the PHPUnit XML file to use for the current $test_id.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Test\PhpUnitTestRunner::xmlLogFilepath() instead.
*
* @see https://www.drupal.org/node/2948547
*/ */
function simpletest_phpunit_xml_filepath($test_id) { function simpletest_phpunit_xml_filepath($test_id) {
return \Drupal::service('file_system')->realpath('public://simpletest') . '/phpunit-' . $test_id . '.xml'; $runner = PhpUnitTestRunner::create(\Drupal::getContainer());
@trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::xmlLogFilepath() instead. See https://www.drupal.org/node/2948547', E_USER_DEPRECATED);
return $runner->xmlLogFilePath($test_id);
} }
/** /**
...@@ -319,65 +292,16 @@ function simpletest_phpunit_configuration_filepath() { ...@@ -319,65 +292,16 @@ function simpletest_phpunit_configuration_filepath() {
* *
* @return string * @return string
* The results as returned by exec(). * The results as returned by exec().
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Test\PhpUnitTestRunner::runCommand() instead.
*
* @see https://www.drupal.org/node/2948547
*/ */
function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpunit_file, &$status = NULL, &$output = NULL) { function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpunit_file, &$status = NULL, &$output = NULL) {
global $base_url; $runner = PhpUnitTestRunner::create(\Drupal::getContainer());
// Setup an environment variable containing the database connection so that @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::runCommand() instead. See https://www.drupal.org/node/2948547', E_USER_DEPRECATED);
// functional tests can connect to the database. return $runner->runCommand($unescaped_test_classnames, $phpunit_file, $status, $output);
putenv('SIMPLETEST_DB=' . Database::getConnectionInfoAsUrl());
// Setup an environment variable containing the base URL, if it is available.
// This allows functional tests to browse the site under test. When running
// tests via CLI, core/phpunit.xml.dist or core/scripts/run-tests.sh can set
// this variable.
if ($base_url) {
putenv('SIMPLETEST_BASE_URL=' . $base_url);
putenv('BROWSERTEST_OUTPUT_DIRECTORY=' . \Drupal::service('file_system')->realpath('public://simpletest'));
}
$phpunit_bin = simpletest_phpunit_command();
$command = [
$phpunit_bin,
'--log-junit',
escapeshellarg($phpunit_file),
'--printer',
escapeshellarg(SimpletestUiPrinter::class),
];
// Optimized for running a single test.
if (count($unescaped_test_classnames) == 1) {
$class = new \ReflectionClass($unescaped_test_classnames[0]);
$command[] = escapeshellarg($class->getFileName());
}
else {
// Double escape namespaces so they'll work in a regexp.
$escaped_test_classnames = array_map(function ($class) {
return addslashes($class);
}, $unescaped_test_classnames);
$filter_string = implode("|", $escaped_test_classnames);
$command = array_merge($command, [
'--filter',
escapeshellarg($filter_string),
]);
}
// Need to change directories before running the command so that we can use
// relative paths in the configuration file's exclusions.
$old_cwd = getcwd();
chdir(\Drupal::root() . "/core");
// exec in a subshell so that the environment is isolated when running tests
// via the simpletest UI.
$ret = exec(implode(" ", $command), $output, $status);
chdir($old_cwd);
putenv('SIMPLETEST_DB=');
if ($base_url) {
putenv('SIMPLETEST_BASE_URL=');
putenv('BROWSERTEST_OUTPUT_DIRECTORY=');
}
return $ret;
} }
/** /**
...@@ -385,24 +309,16 @@ function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpun ...@@ -385,24 +309,16 @@ function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpun
* *
* @return string * @return string
* The command that can be run through exec(). * The command that can be run through exec().
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Test\PhpUnitTestRunner::phpUnitCommand() instead.
*
* @see https://www.drupal.org/node/2948547
*/ */
function simpletest_phpunit_command() { function simpletest_phpunit_command() {
// Load the actual autoloader being used and determine its filename using $runner = PhpUnitTestRunner::create(\Drupal::getContainer());
// reflection. We can determine the vendor directory based on that filename. @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::phpUnitCommand() instead. See https://www.drupal.org/node/2948547', E_USER_DEPRECATED);
$autoloader = require \Drupal::root() . '/autoload.php'; return $runner->phpUnitCommand();
$reflector = new ReflectionClass($autoloader);
$vendor_dir = dirname(dirname($reflector->getFileName()));
// The file in Composer's bin dir is a *nix link, which does not work when
// extracted from a tarball and generally not on Windows.
$command = escapeshellarg($vendor_dir . '/phpunit/phpunit/phpunit');
if (substr(PHP_OS, 0, 3) == 'WIN') {
// On Windows it is necessary to run the script using the PHP executable.
$php_executable_finder = new PhpExecutableFinder();
$php = $php_executable_finder->find();
$command = $php . ' -f ' . $command . ' --';
}
return $command;
} }
/** /**
...@@ -427,7 +343,8 @@ function _simpletest_batch_operation($test_list_init, $test_id, &$context) { ...@@ -427,7 +343,8 @@ function _simpletest_batch_operation($test_list_init, $test_id, &$context) {
// Perform the next test. // Perform the next test.
$test_class = array_shift($test_list); $test_class = array_shift($test_list);
if (is_subclass_of($test_class, TestCase::class)) { if (is_subclass_of($test_class, TestCase::class)) {
$phpunit_results = simpletest_run_phpunit_tests($test_id, [$test_class]); $runner = PhpUnitTestRunner::create(\Drupal::getContainer());
$phpunit_results = $runner->runTests($test_id, [$test_class]);
simpletest_process_phpunit_results($phpunit_results); simpletest_process_phpunit_results($phpunit_results);
$test_results[$test_class] = simpletest_summarize_phpunit_result($phpunit_results)[$test_class]; $test_results[$test_class] = simpletest_summarize_phpunit_result($phpunit_results)[$test_class];
} }
...@@ -805,18 +722,15 @@ function simpletest_mail_alter(&$message) { ...@@ -805,18 +722,15 @@ function simpletest_mail_alter(&$message) {
* The results as array of rows in a format that can be inserted into * The results as array of rows in a format that can be inserted into
* {simpletest}. If the phpunit_xml_file does not have any contents then the * {simpletest}. If the phpunit_xml_file does not have any contents then the
* function will return NULL. * function will return NULL.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Test\JUnitConverter::xmlToRows() instead.
*
* @see https://www.drupal.org/node/2948547
*/ */
function simpletest_phpunit_xml_to_rows($test_id, $phpunit_xml_file) { function simpletest_phpunit_xml_to_rows($test_id, $phpunit_xml_file) {
$contents = @file_get_contents($phpunit_xml_file); @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\JUnitConverter::xmlToRows() instead. See https://www.drupal.org/node/2948547', E_USER_DEPRECATED);
if (!$contents) { return JUnitConverter::xmlToRows($test_id, $phpunit_xml_file) ?: NULL;
return;
}
$records = [];
$testcases = simpletest_phpunit_find_testcases(new SimpleXMLElement($contents));
foreach ($testcases as $testcase) {
$records[] = simpletest_phpunit_testcase_to_row($test_id, $testcase);
}
return $records;
} }
/** /**
...@@ -829,34 +743,15 @@ function simpletest_phpunit_xml_to_rows($test_id, $phpunit_xml_file) { ...@@ -829,34 +743,15 @@ function simpletest_phpunit_xml_to_rows($test_id, $phpunit_xml_file) {
* *
* @return array * @return array
* A list of all test cases. * A list of all test cases.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Test\JUnitConverter::findTestCases() instead.
*
* @see https://www.drupal.org/node/2948547
*/ */
function simpletest_phpunit_find_testcases(\SimpleXMLElement $element, \SimpleXMLElement $parent = NULL) { function simpletest_phpunit_find_testcases(\SimpleXMLElement $element, \SimpleXMLElement $parent = NULL) {
$testcases = []; @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\JUnitConverter::findTestCases() instead. See https://www.drupal.org/node/2948547', E_USER_DEPRECATED);
return JUnitConverter::findTestCases($element, $parent);
if (!isset($parent)) {
$parent = $element;
}
if ($element->getName() === 'testcase' && (int) $parent->attributes()->tests > 0) {
// Add the class attribute if the testcase does not have one. This is the
// case for tests using a data provider. The name of the parent testsuite
// will be in the format class::method.
if (!$element->attributes()->class) {
$name = explode('::', $parent->attributes()->name, 2);
$element->addAttribute('class', $name[0]);
}
$testcases[] = $element;
}
else {
foreach ($element as $child) {
$file = (string) $parent->attributes()->file;
if ($file && !$child->attributes()->file) {
$child->addAttribute('file', $file);
}
$testcases = array_merge($testcases, simpletest_phpunit_find_testcases($child, $element));
}
}
return $testcases;
} }
/** /**
...@@ -864,40 +759,18 @@ function simpletest_phpunit_find_testcases(\SimpleXMLElement $element, \SimpleXM ...@@ -864,40 +759,18 @@ function simpletest_phpunit_find_testcases(\SimpleXMLElement $element, \SimpleXM
* *
* @param int $test_id * @param int $test_id
* The current test ID. * The current test ID.
* @param \SimpleXMLElement $testcase * @param \SimpleXMLElement $test_case
* The PHPUnit test case represented as XML element. * The PHPUnit test case represented as XML element.
* *
* @return array * @return array
* An array containing the {simpletest} result row. * An array containing the {simpletest} result row.
*
* @deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use
* \Drupal\Core\Test\JUnitConverter::convertTestCaseToSimpletestRow() instead.
*
* @see https://www.drupal.org/node/2948547
*/ */
function simpletest_phpunit_testcase_to_row($test_id, \SimpleXMLElement $testcase) { function simpletest_phpunit_testcase_to_row($test_id, \SimpleXMLElement $test_case) {
$message = ''; @trigger_error(__FUNCTION__ . ' is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\JUnitConverter::convertTestCaseToSimpletestRow() instead. See https://www.drupal.org/node/2948547', E_USER_DEPRECATED);
$pass = TRUE; return JUnitConverter::convertTestCaseToSimpletestRow($test_id, $test_case);
if ($testcase->failure) {
$lines = explode("\n", $testcase->failure);
$message = $lines[2];
$pass = FALSE;
}
if ($testcase->error) {
$message = $testcase->error;
$pass = FALSE;
}
$attributes = $testcase->attributes();
$function = $attributes->class . '->' . $attributes->name . '()';
$record = [
'test_id' => $test_id,
'test_class' => (string) $attributes->class,
'status' => $pass ? 'pass' : 'fail',
'message' => $message,
// @todo: Check on the proper values for this.
'message_group' => 'Other',
'function' => $function,
'line' => $attributes->line ?: 0,
// There are situations when the file will not be present because a PHPUnit
// @requires has caused a test to be skipped.
'file' => $attributes->file ?: $function,
];
return $record;
} }
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* Test PHPUnit output for the Simpletest UI. * Test PHPUnit output for the Simpletest UI.
* *
* @group simpletest * @group simpletest
* @group legacy
* *
* @see \Drupal\Tests\Listeners\SimpletestUiPrinter * @see \Drupal\Tests\Listeners\SimpletestUiPrinter
*/ */
......
<?php <?php
namespace Drupal\Tests\simpletest\Unit; namespace Drupal\Tests\simpletest\Kernel;
use Drupal\Tests\UnitTestCase; use Drupal\KernelTests\KernelTestBase;
/** /**
* Tests PHPUnit errors are getting converted to Simpletest errors. * Tests PHPUnit errors are getting converted to Simpletest errors.
* *
* @group simpletest * @group simpletest
* @group legacy
*/ */
class PhpUnitErrorTest extends UnitTestCase { class PhpUnitErrorTest extends KernelTestBase {
/**
* Enable the simpletest module.
*
* @var string[]
*/
protected static $modules = ['simpletest'];
/** /**
* Test errors reported. * Test errors reported.
* *
* @covers ::simpletest_phpunit_xml_to_rows * @expectedDeprecation simpletest_phpunit_xml_to_rows is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\JUnitConverter::xmlToRows() instead. See https://www.drupal.org/node/2948547
*/ */
public function testPhpUnitXmlParsing() { public function testPhpUnitXmlParsing() {
require_once __DIR__ . '/../../../simpletest.module';
$phpunit_error_xml = __DIR__ . '/../../fixtures/phpunit_error.xml'; $phpunit_error_xml = __DIR__ . '/../../fixtures/phpunit_error.xml';
$res = simpletest_phpunit_xml_to_rows(1, $phpunit_error_xml); $res = simpletest_phpunit_xml_to_rows(1, $phpunit_error_xml);
...@@ -34,7 +40,7 @@ public function testPhpUnitXmlParsing() { ...@@ -34,7 +40,7 @@ public function testPhpUnitXmlParsing() {
// Make sure simpletest_phpunit_xml_to_rows() does not balk if the test // Make sure simpletest_phpunit_xml_to_rows() does not balk if the test
// didn't run. // didn't run.
simpletest_phpunit_xml_to_rows(1, 'foobar'); $this->assertNull(simpletest_phpunit_xml_to_rows(1, 'does_not_exist'));
} }
} }
...@@ -34,4 +34,52 @@ public function testDeprecatedServices() { ...@@ -34,4 +34,52 @@ public function testDeprecatedServices() {
$this->assertInstanceOf(TestDiscovery::class, $this->container->get('test_discovery')); $this->assertInstanceOf(TestDiscovery::class, $this->container->get('test_discovery'));
} }
/**
* @expectedDeprecation simpletest_phpunit_xml_filepath is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::xmlLogFilepath() instead. See https://www.drupal.org/node/2948547
* @expectedDeprecation simpletest_phpunit_command is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::phpUnitCommand() instead. See https://www.drupal.org/node/2948547
* @expectedDeprecation simpletest_phpunit_find_testcases is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\JUnitConverter::findTestCases() instead. See https://www.drupal.org/node/2948547
* @expectedDeprecation simpletest_phpunit_testcase_to_row is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\JUnitConverter::convertTestCaseToSimpletestRow() instead. See https://www.drupal.org/node/2948547
* @expectedDeprecation simpletest_summarize_phpunit_result is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::summarizeResults() instead. See https://www.drupal.org/node/2948547
*/
public function testDeprecatedPhpUnitFunctions() {
// We can't test the deprecation errors for the following functions because
// they cannot be mocked, and calling them would change the test results:
// - simpletest_run_phpunit_tests().
// - simpletest_phpunit_run_command().
// - simpletest_phpunit_xml_to_rows().
$this->assertStringEndsWith('/phpunit-23.xml', simpletest_phpunit_xml_filepath(23));
$this->assertInternalType('string', simpletest_phpunit_command());
$this->assertEquals([], simpletest_phpunit_find_testcases(new \SimpleXMLElement('<not_testcase></not_testcase>')));
$this->assertEquals([
'test_id' => 23,
'test_class' => '',
'status' => 'pass',
'message' => '',
'message_group' => 'Other',
'function' => '->()',
'line' => 0,
'file' => NULL,
], simpletest_phpunit_testcase_to_row(23, new \SimpleXMLElement('<not_testcase></not_testcase>')));
$this->assertEquals(
[
static::class => [
'#pass' => 0,
'#fail' => 0,
'#exception' => 0,
'#debug' => 1,
],
],
simpletest_summarize_phpunit_result([
[
'test_class' => static::class,
'status' => 'debug',
],
])
);
}
} }
...@@ -5,15 +5,25 @@ ...@@ -5,15 +5,25 @@
use Drupal\Core\Database\Database; use Drupal\Core\Database\Database;
use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\File\FileSystemInterface; use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Test\PhpUnitTestRunner;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
/** /**
* Tests simpletest_run_phpunit_tests() handles PHPunit fatals correctly. * Tests simpletest_run_phpunit_tests() handles PHPunit fatals correctly.
* *
* We don't extend Drupal\Tests\UnitTestCase here because its $root property is * We don't extend \Drupal\Tests\UnitTestCase here because its $root property is
* not static and we need it to be static here. * not static and we need it to be static here.
* *
* The file simpletest_phpunit_run_command_test.php contains the test class
* \Drupal\Tests\simpletest\Unit\SimpletestPhpunitRunCommandTestWillDie which
* can be made to exit with result code 2. It lives in a file which won't be
* autoloaded, so that it won't fail test runs.
*
* Here, we run SimpletestPhpunitRunCommandTestWillDie, make it die, and see
* what happens.
*
* @group simpletest * @group simpletest
* @group legacy
* *
* @runTestsInSeparateProcesses * @runTestsInSeparateProcesses
* @preserveGlobalState disabled * @preserveGlobalState disabled
...@@ -27,6 +37,13 @@ class SimpletestPhpunitRunCommandTest extends TestCase { ...@@ -27,6 +37,13 @@ class SimpletestPhpunitRunCommandTest extends TestCase {
*/ */
protected static $root; protected static $root;
/**
* A fixture container.
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $fixtureContainer;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -56,6 +73,7 @@ protected function setUp() { ...@@ -56,6 +73,7 @@ protected function setUp() {
$file_system->realpath('public://simpletest')->willReturn(sys_get_temp_dir()); $file_system->realpath('public://simpletest')->willReturn(sys_get_temp_dir());
$container->set('file_system', $file_system->reveal()); $container->set('file_system', $file_system->reveal());
\Drupal::setContainer($container); \Drupal::setContainer($container);
$this->fixtureContainer = $container;
} }
/** /**
...@@ -82,9 +100,14 @@ public function provideStatusCodes() { ...@@ -82,9 +100,14 @@ public function provideStatusCodes() {
/** /**
* Test the round trip for PHPUnit execution status codes. * Test the round trip for PHPUnit execution status codes.
* *
* Also tests backwards-compatibility of PhpUnitTestRunner::runTests().
*
* @covers ::simpletest_run_phpunit_tests * @covers ::simpletest_run_phpunit_tests
* *
* @dataProvider provideStatusCodes * @dataProvider provideStatusCodes
*
* @expectedDeprecation simpletest_run_phpunit_tests is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::runTests() instead. See https://www.drupal.org/node/2948547
* @expectedDeprecation simpletest_phpunit_xml_filepath is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Test\PhpUnitTestRunner::xmlLogFilepath() instead. See https://www.drupal.org/node/2948547
*/ */
public function testSimpletestPhpUnitRunCommand($status, $label) { public function testSimpletestPhpUnitRunCommand($status, $label) {
// Add a default database connection in order for // Add a default database connection in order for
...@@ -101,8 +124,17 @@ public function testSimpletestPhpUnitRunCommand($status, $label) { ...@@ -101,8 +124,17 @@ public function testSimpletestPhpUnitRunCommand($status, $label) {
); );
$test_id = basename(tempnam(sys_get_temp_dir(), 'xxx')); $test_id = basename(tempnam(sys_get_temp_dir(), 'xxx'));
putenv('SimpletestPhpunitRunCommandTestWillDie=' . $status); putenv('SimpletestPhpunitRunCommandTestWillDie=' . $status);
$ret = simpletest_run_phpunit_tests($test_id, [SimpletestPhpunitRunCommandTestWillDie::class]);
// Test against simpletest_run_phpunit_tests().
$bc_ret = simpletest_run_phpunit_tests($test_id, [SimpletestPhpunitRunCommandTestWillDie::class]);
$this->assertSame($bc_ret[0]['status'], $label);
// Test against PhpUnitTestRunner::runTests().
$runner = PhpUnitTestRunner::create($this->fixtureContainer);
$ret = $runner->runTests($test_id, [SimpletestPhpunitRunCommandTestWillDie::class]);
$this->assertSame($ret[0]['status'], $label); $this->assertSame($ret[0]['status'], $label);
// Unset our environmental variable.
putenv('SimpletestPhpunitRunCommandTestWillDie'); putenv('SimpletestPhpunitRunCommandTestWillDie');
unlink(simpletest_phpunit_xml_filepath($test_id)); unlink(simpletest_phpunit_xml_filepath($test_id));
} }
......
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
use Drupal\Core\File\Exception\FileException; use Drupal\Core\File\Exception\FileException;
use Drupal\Core\File\FileSystemInterface; use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\StreamWrapper\PublicStream; use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\Core\Test\PhpUnitTestRunner;
use Drupal\Core\Test\TestDatabase; use Drupal\Core\Test\TestDatabase;
use Drupal\Core\Test\TestRunnerKernel; use Drupal\Core\Test\TestRunnerKernel;
use Drupal\simpletest\Form\SimpletestResultsForm; use Drupal\simpletest\Form\SimpletestResultsForm;
use Drupal\simpletest\TestBase;
use Drupal\Core\Test\TestDiscovery; use Drupal\Core\Test\TestDiscovery;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use PHPUnit\Runner\Version; use PHPUnit\Runner\Version;
...@@ -789,12 +789,11 @@ function simpletest_script_run_phpunit($test_id, $class) { ...@@ -789,12 +789,11 @@ function simpletest_script_run_phpunit($test_id, $class) {
set_time_limit($reflection->getStaticPropertyValue('runLimit')); set_time_limit($reflection->getStaticPropertyValue('runLimit'));
} }
$results = simpletest_run_phpunit_tests($test_id, [$class], $status); $runner = PhpUnitTestRunner::create(\Drupal::getContainer());
$results = $runner->runTests($test_id, [$class], $status);
simpletest_process_phpunit_results($results); simpletest_process_phpunit_results($results);
// Map phpunit results to a data structure we can pass to $summaries = $runner->summarizeResults($results);
// _simpletest_format_summary_line.
$summaries = simpletest_summarize_phpunit_result($results);
foreach ($summaries as $class => $summary) { foreach ($summaries as $class => $summary) {
simpletest_script_reporter_display_summary($class, $summary); simpletest_script_reporter_display_summary($class, $summary);
} }
......
<?php
namespace Drupal\Tests\Core\Test;
use Drupal\Core\Test\JUnitConverter;
use Drupal\Tests\UnitTestCase;
use org\bovigo\vfs\vfsStream;
/**
* Tests Drupal\Core\Test\JUnitConverter.
*
* This test class has significant overlap with
* Drupal\Tests\simpletest\Kernel\PhpUnitErrorTest.
*
* @coversDefaultClass \Drupal\Core\Test\JUnitConverter
*
* @group Test
* @group simpletest
*
* @see \Drupal\Tests\simpletest\Kernel\PhpUnitErrorTest
*/
class JUnitConverterTest extends UnitTestCase {
/**
* Test errors reported.
* @covers ::xmlToRows
*/
public function testXmlToRowsWithErrors() {
$phpunit_error_xml = __DIR__ . '/fixtures/phpunit_error.xml';
$res = JUnitConverter::xmlToRows(1, $phpunit_error_xml);
$this->assertEquals(count($res), 4, 'All testcases got extracted');
$this->assertNotEquals($res[0]['status'], 'pass');
$this->assertEquals($res[0]['status'], 'fail');
// Test nested testsuites, which appear when you use @dataProvider.
for ($i = 0; $i < 3; $i++) {
$this->assertNotEquals($res[$i + 1]['status'], 'pass');
$this->assertEquals($res[$i + 1]['status'], 'fail');
}
// Make sure xmlToRows() does not balk if there are no test results.
$this->assertSame([], JUnitConverter::xmlToRows(1, 'does_not_exist'));
}
/**
* @covers ::xmlToRows
*/
public function testXmlToRowsEmptyFile() {
// File system with an empty XML file.
vfsStream::setup('junit_test', NULL, ['empty.xml' => '']);
$this->assertArrayEquals([], JUnitConverter::xmlToRows(23, vfsStream::url('junit_test/empty.xml')));
}
/**
* @covers ::xmlElementToRows
*/
public function testXmlElementToRows() {
$junit = <<<EOD
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="Drupal\Tests\simpletest\Unit\TestDiscoveryTest" file="/Users/paul/projects/drupal/core/modules/simpletest/tests/src/Unit/TestDiscoveryTest.php" tests="3" assertions="5" errors="0" failures="0" skipped="0" time="0.215539">
<testcase name="testGetTestClasses" class="Drupal\Tests\simpletest\Unit\TestDiscoveryTest" classname="Drupal.Tests.simpletest.Unit.TestDiscoveryTest" file="/Users/paul/projects/drupal/core/modules/simpletest/tests/src/Unit/TestDiscoveryTest.php" line="108" assertions="2" time="0.100787"/>
</testsuite>
</testsuites>
EOD;
$simpletest = [
[
'test_id' => 23,
'test_class' => 'Drupal\Tests\simpletest\Unit\TestDiscoveryTest',
'status' => 'pass',
'message' => '',
'message_group' => 'Other',
'function' => 'Drupal\Tests\simpletest\Unit\TestDiscoveryTest->testGetTestClasses()',
'line' => 108,
'file' => '/Users/paul/projects/drupal/core/modules/simpletest/tests/src/Unit/TestDiscoveryTest.php',
],
];
$this->assertArrayEquals($simpletest, JUnitConverter::xmlElementToRows(23, new \SimpleXMLElement($junit)));
}
/**
* @covers ::convertTestCaseToSimpletestRow
*/
public function testConvertTestCaseToSimpletestRow() {
$junit = <<<EOD
<testcase name="testGetTestClasses" class="Drupal\Tests\simpletest\Unit\TestDiscoveryTest" classname="Drupal.Tests.simpletest.Unit.TestDiscoveryTest" file="/Users/paul/projects/drupal/core/modules/simpletest/tests/src/Unit/TestDiscoveryTest.php" line="108" assertions="2" time="0.100787"/>
EOD;
$simpletest = [
'test_id' => 23,
'test_class' => 'Drupal\Tests\simpletest\Unit\TestDiscoveryTest',
'status' => 'pass',
'message' => '',
'message_group' => 'Other',
'function' => 'Drupal\Tests\simpletest\Unit\TestDiscoveryTest->testGetTestClasses()',
'line' => 108,
'file' => '/Users/paul/projects/drupal/core/modules/simpletest/tests/src/Unit/TestDiscoveryTest.php',
];
$this->assertArrayEquals($simpletest, JUnitConverter::convertTestCaseToSimpletestRow(23, new \SimpleXMLElement($junit)));
}
}
<?php
namespace Drupal\Tests\Core\Test;
use Drupal\Core\Test\PhpUnitTestRunner;
use Drupal\Core\Test\TestStatus;
use Drupal\Tests\UnitTestCase;
/**
* @coversDefaultClass \Drupal\Core\Test\PhpUnitTestRunner
* @group Test
*
* @see Drupal\Tests\simpletest\Unit\SimpletestPhpunitRunCommandTest
*/
class PhpUnitTestRunnerTest extends UnitTestCase {
/**
* Test an error in the test running phase.
*
* @covers ::runTests
*/
public function testRunTestsError() {
$test_id = 23;
$log_path = 'test_log_path';
// Create a mock runner.
$runner = $this->getMockBuilder(PhpUnitTestRunner::class)
->disableOriginalConstructor()
->setMethods(['xmlLogFilepath', 'runCommand'])
->getMock();
// Set some expectations for xmlLogFilepath().
$runner->expects($this->once())
->method('xmlLogFilepath')
->willReturn($log_path);
// We mark a failure by having runCommand() deliver a serious status code.
$runner->expects($this->once())
->method('runCommand')
->willReturnCallback(
function ($unescaped_test_classnames, $phpunit_file, &$status) {
$status = TestStatus::EXCEPTION;
}
);
// The runTests() method expects $status by reference, so we initialize it
// to some value we don't expect back.
$status = -1;
$results = $runner->runTests($test_id, ['SomeTest'], $status);
// Make sure our status code made the round trip.
$this->assertEquals(TestStatus::EXCEPTION, $status);
// A serious error in runCommand() should give us a fixed set of results.
$row = reset($results);
$fail_row = [
'test_id' => $test_id,
'test_class' => 'SomeTest',
'status' => TestStatus::label(TestStatus::EXCEPTION),
'message' => 'PHPunit Test failed to complete; Error: ',
'message_group' => 'Other',
'function' => 'SomeTest',
'line' => '0',
'file' => $log_path,
];
$this->assertEquals($fail_row, $row);
}
/**
* @covers ::phpUnitCommand
*/
public function testPhpUnitCommand() {
$runner = new PhpUnitTestRunner($this->root, sys_get_temp_dir());
$this->assertRegExp('/phpunit/', $runner->phpUnitCommand());
}
/**
* @covers ::xmlLogFilePath
*/
public function testXmlLogFilePath() {
$runner = new PhpUnitTestRunner($this->root, sys_get_temp_dir());
$this->assertStringEndsWith('phpunit-23.xml', $runner->xmlLogFilePath(23));
}
public function providerTestSummarizeResults() {
return [
[
[
[
'test_class' => static::class,
'status' => 'pass',
],
],
'#pass',
],
[
[
[
'test_class' => static::class,
'status' => 'fail',
],
],
'#fail',
],
[
[
[
'test_class' => static::class,
'status' => 'exception',
],
],
'#exception',
],
[
[
[
'test_class' => static::class,
'status' => 'debug',
],
],
'#debug',
],
];
}
/**
* @dataProvider providerTestSummarizeResults
* @covers ::summarizeResults
*/
public function testSummarizeResults($results, $has_status) {
$runner = new PhpUnitTestRunner($this->root, sys_get_temp_dir());
$summary = $runner->summarizeResults($results);
$this->assertArrayHasKey(static::class, $summary);
$this->assertEquals(1, $summary[static::class][$has_status]);
foreach (array_diff(['#pass', '#fail', '#exception', '#debug'], [$has_status]) as $should_be_zero) {
$this->assertSame(0, $summary[static::class][$should_be_zero]);
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="Drupal Unit Test Suite" tests="1" assertions="0" failures="0" errors="1" time="0.002680">
<testsuite name="Drupal\Tests\Component\PhpStorage\FileStorageTest" file="/home/chx/www/system/core/tests/Drupal/Tests/Component/PhpStorage/FileStorageTest.php" namespace="Drupal\Tests\Component\PhpStorage" fullPackage="Drupal.Tests.Component.PhpStorage" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
<testsuite name="Drupal\Tests\Component\PhpStorage\MTimeProtectedFastFileStorageTest" file="/home/chx/www/system/core/tests/Drupal/Tests/Component/PhpStorage/MTimeProtectedFastFileStorageTest.php" namespace="Drupal\Tests\Component\PhpStorage" fullPackage="Drupal.Tests.Component.PhpStorage" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
<testsuite name="Drupal\Tests\Core\Cache\BackendChainImplementationUnitTest" file="/home/chx/www/system/core/tests/Drupal/Tests/Core/Cache/BackendChainImplementationUnitTest.php" namespace="Drupal\Tests\Core\Cache" fullPackage="Drupal.Tests.Core.Cache" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
<testsuite name="Drupal\Tests\Core\Cache\NullBackendTest" file="/home/chx/www/system/core/tests/Drupal/Tests/Core/Cache/NullBackendTest.php" namespace="Drupal\Tests\Core\Cache" fullPackage="Drupal.Tests.Core.Cache" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
<testsuite name="Drupal\Tests\Core\Extension\ModuleHandlerUnitTest" file="/home/chx/www/system/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerUnitTest.php" namespace="Drupal\Tests\Core\Extension" fullPackage="Drupal.Tests.Core.Extension" tests="1" assertions="0" failures="0" errors="1" time="0.002680">
<testcase name="testloadInclude" class="Drupal\Tests\Core\Extension\ModuleHandlerUnitTest" file="/home/chx/www/system/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerUnitTest.php" line="37" assertions="0" time="0.002680">
<error type="PHPUnit_Framework_Error_Notice">Drupal\Tests\Core\Extension\ModuleHandlerUnitTest::testloadInclude
Undefined index: foo
/home/chx/www/system/core/lib/Drupal/Core/Extension/ModuleHandler.php:219
/home/chx/www/system/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerUnitTest.php:40
</error>
</testcase>
</testsuite>
<testsuite name="Drupal\Tests\Core\NestedArrayUnitTest" file="/home/chx/www/system/core/tests/Drupal/Tests/Core/NestedArrayUnitTest.php" namespace="Drupal\Tests\Core" fullPackage="Drupal.Tests.Core" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
<testsuite name="Drupal\breakpoint\Tests\BreakpointMediaQueryTest" file="/home/chx/www/system/core/modules/breakpoint/tests/Drupal/breakpoint/Tests/BreakpointMediaQueryTest.php" namespace="Drupal\breakpoint\Tests" fullPackage="Drupal.breakpoint.Tests" tests="0" assertions="0" failures="0" errors="0" time="0.000000"/>
<testsuite name="Drupal\Tests\Core\Route\RoleAccessCheckTest" file="/var/www/d8/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTestkTest.php" namespace="Drupal\Tests\Core\Route" fullPackage="Drupal.Tests.Core.Route" tests="3" assertions="3" failures="3" errors="0" time="0.009176">
<testsuite name="Drupal\Tests\Core\Route\RoleAccessCheckTest::testRoleAccess" tests="3" assertions="3" failures="3" errors="0" time="0.009176">
<testcase name="testRoleAccess with data set #0" assertions="1" time="0.004519">
<failure type="PHPUnit_Framework_ExpectationFailedException">Drupal\Tests\Core\Route\RoleAccessCheckTest::testRoleAccess with data set #0 ('role_test_1', array(Drupal\user\Entity\User, Drupal\user\Entity\User))
Access granted for user with the roles role_test_1 on path: role_test_1
Failed asserting that false is true.
</failure>
</testcase>
<testcase name="testRoleAccess with data set #1" assertions="1" time="0.002354">
<failure type="PHPUnit_Framework_ExpectationFailedException">Drupal\Tests\Core\Route\RoleAccessCheckTest::testRoleAccess with data set #1 ('role_test_2', array(Drupal\user\Entity\User, Drupal\user\Entity\User))
Access granted for user with the roles role_test_2 on path: role_test_2
Failed asserting that false is true.
</failure>
</testcase>
<testcase name="testRoleAccess with data set #2" assertions="1" time="0.002303">
<failure type="PHPUnit_Framework_ExpectationFailedException">Drupal\Tests\Core\Route\RoleAccessCheckTest::testRoleAccess with data set #2 ('role_test_3', array(Drupal\user\Entity\User))
Access granted for user with the roles role_test_1, role_test_2 on path: role_test_3
Failed asserting that false is true.
</failure>
</testcase>
</testsuite>
</testsuite>
</testsuite>
</testsuites>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment