<?php
namespace Codeception\PHPUnit;
use Codeception\Configuration;
use Codeception\Exception\ConfigurationException;
class Runner extends \PHPUnit\TextUI\TestRunner
{
public static $persistentListeners = [];
protected $defaultListeners = [
'xml' => false,
'phpunit-xml' => false,
'html' => false,
'tap' => false,
'json' => false,
'report' => false
];
protected $config = [];
protected $logDir = null;
public function __construct()
{
$this->config = Configuration::config();
$this->logDir = Configuration::outputDir(); // prepare log dir
$this->phpUnitOverriders();
parent::__construct();
}
public function phpUnitOverriders()
{
require_once __DIR__ . DIRECTORY_SEPARATOR . 'Overrides/Filter.php';
}
/**
* @return null|\PHPUnit\TextUI\ResultPrinter
*/
public function getPrinter()
{
return $this->printer;
}
public function prepareSuite(\PHPUnit\Framework\Test $suite, array &$arguments)
{
$this->handleConfiguration($arguments);
$filterFactory = new \PHPUnit\Runner\Filter\Factory();
if ($arguments['groups']) {
$filterFactory->addFilter(
new \ReflectionClass('PHPUnit\Runner\Filter\IncludeGroupFilterIterator'),
$arguments['groups']
);
}
if ($arguments['excludeGroups']) {
$filterFactory->addFilter(
new \ReflectionClass('PHPUnit\Runner\Filter\ExcludeGroupFilterIterator'),
$arguments['excludeGroups']
);
}
if ($arguments['filter']) {
$filterFactory->addFilter(
new \ReflectionClass('Codeception\PHPUnit\FilterTest'),
$arguments['filter']
);
}
$suite->injectFilter($filterFactory);
}
public function doEnhancedRun(
\PHPUnit\Framework\Test $suite,
\PHPUnit\Framework\TestResult $result,
array $arguments = []
) {
unset($GLOBALS['app']); // hook for not to serialize globals
$result->convertErrorsToExceptions(false);
if (isset($arguments['report_useless_tests'])) {
$result->beStrictAboutTestsThatDoNotTestAnything((bool)$arguments['report_useless_tests']);
}
if (isset($arguments['disallow_test_output'])) {
$result->beStrictAboutOutputDuringTests((bool)$arguments['disallow_test_output']);
}
if (empty(self::$persistentListeners)) {
$this->applyReporters($result, $arguments);
}
if (class_exists('\Symfony\Bridge\PhpUnit\SymfonyTestsListener')) {
$arguments['listeners'] = isset($arguments['listeners']) ? $arguments['listeners'] : [];
$listener = new \Symfony\Bridge\PhpUnit\SymfonyTestsListener();
$listener->globalListenerDisabled();
$arguments['listeners'][] = $listener;
}
$arguments['listeners'][] = $this->printer;
// clean up listeners between suites
foreach ($arguments['listeners'] as $listener) {
$result->addListener($listener);
}
$suite->run($result);
unset($suite);
foreach ($arguments['listeners'] as $listener) {
$result->removeListener($listener);
}
return $result;
}
/**
* @param \PHPUnit\Framework\TestResult $result
* @param array $arguments
*
* @return array
*/
protected function applyReporters(\PHPUnit\Framework\TestResult $result, array $arguments)
{
foreach ($this->defaultListeners as $listener => $value) {
if (!isset($arguments[$listener])) {
$arguments[$listener] = $value;
}
}
if ($arguments['report']) {
self::$persistentListeners[] = $this->instantiateReporter('report');
}
if ($arguments['html']) {
codecept_debug('Printing HTML report into ' . $arguments['html']);
self::$persistentListeners[] = $this->instantiateReporter(
'html',
[$this->absolutePath($arguments['html'])]
);
}
if ($arguments['xml']) {
codecept_debug('Printing JUNIT report into ' . $arguments['xml']);
self::$persistentListeners[] = $this->instantiateReporter(
'xml',
[$this->absolutePath($arguments['xml']), (bool)$arguments['log_incomplete_skipped']]
);
}
if ($arguments['phpunit-xml']) {
codecept_debug('Printing PHPUNIT report into ' . $arguments['phpunit-xml']);
self::$persistentListeners[] = $this->instantiateReporter(
'phpunit-xml',
[$this->absolutePath($arguments['phpunit-xml']), (bool)$arguments['log_incomplete_skipped']]
);
}
if ($arguments['tap']) {
codecept_debug('Printing TAP report into ' . $arguments['tap']);
self::$persistentListeners[] = $this->instantiateReporter('tap', [$this->absolutePath($arguments['tap'])]);
}
if ($arguments['json']) {
codecept_debug('Printing JSON report into ' . $arguments['json']);
self::$persistentListeners[] = $this->instantiateReporter(
'json',
[$this->absolutePath($arguments['json'])]
);
}
foreach (self::$persistentListeners as $listener) {
if ($listener instanceof ConsolePrinter) {
$this->printer = $listener;
continue;
}
$result->addListener($listener);
}
}
protected function instantiateReporter($name, $args = [])
{
if (!isset($this->config['reporters'][$name])) {
throw new ConfigurationException("Reporter $name not defined");
}
return (new \ReflectionClass($this->config['reporters'][$name]))->newInstanceArgs($args);
}
private function absolutePath($path)
{
if ((strpos($path, '/') === 0) or (strpos($path, ':') === 1)) { // absolute path
return $path;
}
return $this->logDir . $path;
}
}
|