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 Drupal\Console\Core\Command\Command;
16 use Drupal\Console\Annotations\DrupalCommand;
17 use Drupal\Core\Extension\ModuleHandlerInterface;
18 use Drupal\simpletest\TestDiscovery;
19 use Drupal\Core\Datetime\DateFormatter;
23 * extension = "simpletest",
24 * extensionType = "module",
27 class RunCommand extends Command
37 protected $test_discovery;
41 * @var ModuleHandlerInterface
43 protected $moduleHandler;
49 protected $dateFormatter;
52 * RunCommand constructor.
55 * @param TestDiscovery $test_discovery
56 * @param ModuleHandlerInterface $moduleHandler
58 public function __construct(
60 TestDiscovery $test_discovery,
61 ModuleHandlerInterface $moduleHandler,
62 DateFormatter $dateFormatter
64 $this->appRoot = $appRoot;
65 $this->test_discovery = $test_discovery;
66 $this->moduleHandler = $moduleHandler;
67 $this->dateFormatter = $dateFormatter;
68 parent::__construct();
71 protected function configure()
75 ->setDescription($this->trans('commands.test.run.description'))
78 InputArgument::REQUIRED,
79 $this->trans('commands.test.run.arguments.test-class')
83 InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
84 $this->trans('commands.test.run.arguments.test-methods')
89 InputOption::VALUE_REQUIRED,
90 $this->trans('commands.test.run.arguments.url')
92 ->setAliases(['ter']);
96 * Set Server variable to be used in test cases.
102 protected function execute(InputInterface $input, OutputInterface $output)
104 //Registers namespaces for disabled modules.
105 $this->test_discovery->registerTestNamespaces();
107 $testClass = $input->getArgument('test-class');
108 $testMethods = $input->getArgument('test-methods');
110 $url = $input->getOption('url');
113 $this->getIo()->error($this->trans('commands.test.run.messages.url-required'));
117 $this->setEnvironment($url);
119 // Create simpletest test id
120 $testId = db_insert('simpletest_test_id')
121 ->useDefaults(['test_id'])
124 if (is_subclass_of($testClass, 'PHPUnit_Framework_TestCase')) {
125 $this->getIo()->info($this->trans('commands.test.run.messages.phpunit-pending'));
128 if (!class_exists($testClass)) {
129 $this->getIo()->error(
131 $this->trans('commands.test.run.messages.invalid-class'),
139 $test = new $testClass($testId);
140 $this->getIo()->info($this->trans('commands.test.run.messages.starting-test'));
141 Timer::start('run-tests');
143 $test->run($testMethods);
145 $end = Timer::stop('run-tests');
147 $this->getIo()->simple(
148 $this->trans('commands.test.run.messages.test-duration') . ': ' . $this->dateFormatter->formatInterval($end['time'] / 1000)
150 $this->getIo()->simple(
151 $this->trans('commands.test.run.messages.test-pass') . ': ' . $test->results['#pass']
153 $this->getIo()->commentBlock(
154 $this->trans('commands.test.run.messages.test-fail') . ': ' . $test->results['#fail']
156 $this->getIo()->commentBlock(
157 $this->trans('commands.test.run.messages.test-exception') . ': ' . $test->results['#exception']
159 $this->getIo()->simple(
160 $this->trans('commands.test.run.messages.test-debug') . ': ' . $test->results['#debug']
163 $this->moduleHandler->invokeAll(
168 $this->getIo()->newLine();
169 $this->getIo()->info($this->trans('commands.test.run.messages.test-summary'));
170 $this->getIo()->newLine();
172 $currentClass = null;
173 $currentGroup = null;
174 $currentStatus = null;
176 $messages = $this->simpletestScriptLoadMessagesByTestIds([$testId]);
178 foreach ($messages as $message) {
179 if ($currentClass === null || $currentClass != $message->test_class) {
180 $currentClass = $message->test_class;
181 $this->getIo()->comment($message->test_class);
184 if ($currentGroup === null || $currentGroup != $message->message_group) {
185 $currentGroup = $message->message_group;
188 if ($currentStatus === null || $currentStatus != $message->status) {
189 $currentStatus = $message->status;
190 if ($message->status == 'fail') {
191 $this->getIo()->error($this->trans('commands.test.run.messages.group') . ':' . $message->message_group . ' ' . $this->trans('commands.test.run.messages.status') . ':' . $message->status);
192 $this->getIo()->newLine();
194 $this->getIo()->info($this->trans('commands.test.run.messages.group') . ':' . $message->message_group . ' ' . $this->trans('commands.test.run.messages.status') . ':' . $message->status);
195 $this->getIo()->newLine();
199 $this->getIo()->simple(
200 $this->trans('commands.test.run.messages.file') . ': ' . str_replace($this->appRoot, '', $message->file)
202 $this->getIo()->simple(
203 $this->trans('commands.test.run.messages.method') . ': ' . $message->function
205 $this->getIo()->simple(
206 $this->trans('commands.test.run.messages.line') . ': ' . $message->line
208 $this->getIo()->simple(
209 $this->trans('commands.test.run.messages.message') . ': ' . $message->message
211 $this->getIo()->newLine();
217 protected function setEnvironment($url)
219 $base_url = 'http://';
222 $parsed_url = parse_url($url);
223 $host = $parsed_url['host'] . (isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '');
224 $path = isset($parsed_url['path']) ? rtrim(rtrim($parsed_url['path']), '/') : '';
225 $port = (isset($parsed_url['port']) ? $parsed_url['port'] : $port);
229 // If the passed URL schema is 'https' then setup the $_SERVER variables
230 // properly so that testing will run under HTTPS.
231 if ($parsed_url['scheme'] == 'https') {
232 $_SERVER['HTTPS'] = 'on';
236 if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') {
237 $base_url = 'https://';
243 putenv('SIMPLETEST_BASE_URL=' . $base_url);
244 $_SERVER['HTTP_HOST'] = $host;
245 $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
246 $_SERVER['SERVER_ADDR'] = '127.0.0.1';
247 $_SERVER['SERVER_PORT'] = $port;
248 $_SERVER['SERVER_SOFTWARE'] = null;
249 $_SERVER['SERVER_NAME'] = 'localhost';
250 $_SERVER['REQUEST_URI'] = $path . '/';
251 $_SERVER['REQUEST_METHOD'] = 'GET';
252 $_SERVER['SCRIPT_NAME'] = $path . '/index.php';
253 $_SERVER['SCRIPT_FILENAME'] = $path . '/index.php';
254 $_SERVER['PHP_SELF'] = $path . '/index.php';
255 $_SERVER['HTTP_USER_AGENT'] = 'Drupal Console';
259 * Get Simletests log after execution
262 protected function simpletestScriptLoadMessagesByTestIds($test_ids)
266 foreach ($test_ids as $test_id) {
267 $result = \Drupal::database()->query(
268 "SELECT * FROM {simpletest} WHERE test_id = :test_id ORDER BY test_class, message_group, status", [
269 ':test_id' => $test_id,
273 $results = array_merge($results, $result);