5 * Contains \Drupal\Console\Command\Test\DebugCommand.
8 namespace Drupal\Console\Command\Test;
10 use Symfony\Component\Console\Input\InputArgument;
11 use Symfony\Component\Console\Input\InputOption;
12 use Symfony\Component\Console\Input\InputInterface;
13 use Symfony\Component\Console\Output\OutputInterface;
14 use Drupal\Component\Utility\Timer;
15 use Symfony\Component\Console\Command\Command;
16 use Drupal\Console\Core\Command\Shared\CommandTrait;
17 use Drupal\Console\Annotations\DrupalCommand;
18 use Drupal\Console\Core\Style\DrupalStyle;
19 use Drupal\Core\Extension\ModuleHandlerInterface;
20 use Drupal\simpletest\TestDiscovery;
21 use Drupal\Core\Datetime\DateFormatter;
25 * extension = "simpletest",
26 * extensionType = "module",
29 class RunCommand extends Command
41 protected $test_discovery;
45 * @var ModuleHandlerInterface
47 protected $moduleHandler;
53 protected $dateFormatter;
58 * RunCommand constructor.
61 * @param TestDiscovery $test_discovery
62 * @param ModuleHandlerInterface $moduleHandler
64 public function __construct(
66 TestDiscovery $test_discovery,
67 ModuleHandlerInterface $moduleHandler,
68 DateFormatter $dateFormatter
70 $this->appRoot = $appRoot;
71 $this->test_discovery = $test_discovery;
72 $this->moduleHandler = $moduleHandler;
73 $this->dateFormatter = $dateFormatter;
74 parent::__construct();
77 protected function configure()
81 ->setDescription($this->trans('commands.test.run.description'))
84 InputArgument::REQUIRED,
85 $this->trans('commands.test.run.arguments.test-class')
89 InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
90 $this->trans('commands.test.run.arguments.test-methods')
95 InputOption::VALUE_REQUIRED,
96 $this->trans('commands.test.run.arguments.url')
101 * Set Server variable to be used in test cases.
107 protected function execute(InputInterface $input, OutputInterface $output)
109 $io = new DrupalStyle($input, $output);
111 //Registers namespaces for disabled modules.
112 $this->test_discovery->registerTestNamespaces();
114 $testClass = $input->getArgument('test-class');
115 $testMethods = $input->getArgument('test-methods');
117 $url = $input->getOption('url');
120 $io->error($this->trans('commands.test.run.messages.url-required'));
124 $this->setEnvironment($url);
126 // Create simpletest test id
127 $testId = db_insert('simpletest_test_id')
128 ->useDefaults(['test_id'])
131 if (is_subclass_of($testClass, 'PHPUnit_Framework_TestCase')) {
132 $io->info($this->trans('commands.test.run.messages.phpunit-pending'));
135 if (!class_exists($testClass)) {
138 $this->trans('commands.test.run.messages.invalid-class'),
146 $test = new $testClass($testId);
147 $io->info($this->trans('commands.test.run.messages.starting-test'));
148 Timer::start('run-tests');
150 $test->run($testMethods);
152 $end = Timer::stop('run-tests');
155 $this->trans('commands.test.run.messages.test-duration') . ': ' . $this->dateFormatter->formatInterval($end['time'] / 1000)
158 $this->trans('commands.test.run.messages.test-pass') . ': ' . $test->results['#pass']
161 $this->trans('commands.test.run.messages.test-fail') . ': ' . $test->results['#fail']
164 $this->trans('commands.test.run.messages.test-exception') . ': ' . $test->results['#exception']
167 $this->trans('commands.test.run.messages.test-debug') . ': ' . $test->results['#debug']
170 $this->moduleHandler->invokeAll(
176 $io->info($this->trans('commands.test.run.messages.test-summary'));
179 $currentClass = null;
180 $currentGroup = null;
181 $currentStatus = null;
183 $messages = $this->simpletestScriptLoadMessagesByTestIds([$testId]);
185 foreach ($messages as $message) {
186 if ($currentClass === null || $currentClass != $message->test_class) {
187 $currentClass = $message->test_class;
188 $io->comment($message->test_class);
191 if ($currentGroup === null || $currentGroup != $message->message_group) {
192 $currentGroup = $message->message_group;
195 if ($currentStatus === null || $currentStatus != $message->status) {
196 $currentStatus = $message->status;
197 if ($message->status == 'fail') {
198 $io->error($this->trans('commands.test.run.messages.group') . ':' . $message->message_group . ' ' . $this->trans('commands.test.run.messages.status') . ':' . $message->status);
201 $io->info($this->trans('commands.test.run.messages.group') . ':' . $message->message_group . ' ' . $this->trans('commands.test.run.messages.status') . ':' . $message->status);
207 $this->trans('commands.test.run.messages.file') . ': ' . str_replace($this->appRoot, '', $message->file)
210 $this->trans('commands.test.run.messages.method') . ': ' . $message->function
213 $this->trans('commands.test.run.messages.line') . ': ' . $message->line
216 $this->trans('commands.test.run.messages.message') . ': ' . $message->message
224 protected function setEnvironment($url)
226 $base_url = 'http://';
229 $parsed_url = parse_url($url);
230 $host = $parsed_url['host'] . (isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '');
231 $path = isset($parsed_url['path']) ? rtrim(rtrim($parsed_url['path']), '/') : '';
232 $port = (isset($parsed_url['port']) ? $parsed_url['port'] : $port);
236 // If the passed URL schema is 'https' then setup the $_SERVER variables
237 // properly so that testing will run under HTTPS.
238 if ($parsed_url['scheme'] == 'https') {
239 $_SERVER['HTTPS'] = 'on';
243 if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
244 $base_url = 'https://';
250 putenv('SIMPLETEST_BASE_URL=' . $base_url);
251 $_SERVER['HTTP_HOST'] = $host;
252 $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
253 $_SERVER['SERVER_ADDR'] = '127.0.0.1';
254 $_SERVER['SERVER_PORT'] = $port;
255 $_SERVER['SERVER_SOFTWARE'] = null;
256 $_SERVER['SERVER_NAME'] = 'localhost';
257 $_SERVER['REQUEST_URI'] = $path . '/';
258 $_SERVER['REQUEST_METHOD'] = 'GET';
259 $_SERVER['SCRIPT_NAME'] = $path . '/index.php';
260 $_SERVER['SCRIPT_FILENAME'] = $path . '/index.php';
261 $_SERVER['PHP_SELF'] = $path . '/index.php';
262 $_SERVER['HTTP_USER_AGENT'] = 'Drupal Console';
266 * Get Simletests log after execution
269 protected function simpletestScriptLoadMessagesByTestIds($test_ids)
273 foreach ($test_ids as $test_id) {
274 $result = \Drupal::database()->query(
275 "SELECT * FROM {simpletest} WHERE test_id = :test_id ORDER BY test_class, message_group, status", [
276 ':test_id' => $test_id,
280 $results = array_merge($results, $result);