/** * Runs all tests. * @return void */ public function run() { $count = 0; $failed = $passed = $skipped = array(); exec($this->phpEnvironment . escapeshellarg($this->phpBinary) . ' -v', $output); echo "{$output['0']} | {$this->phpBinary} {$this->phpArgs} {$this->phpEnvironment}\n\n"; $tests = array(); foreach ($this->paths as $path) { if (is_file($path)) { $files = array($path); } else { $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); } foreach ($files as $entry) { $entry = (string) $entry; $info = pathinfo($entry); if (!isset($info['extension']) || $info['extension'] !== 'phpt') { continue; } $tests[] = $entry; } } $running = array(); while ($tests || $running) { for ($i = count($running); $tests && $i < $this->jobs; $i++) { $entry = array_shift($tests); $count++; $testCase = new TestCase($entry); $testCase->setPhp($this->phpBinary, $this->phpArgs, $this->phpEnvironment); try { $parallel = $this->jobs > 1 && count($running) + count($tests) > 1; $running[$entry] = $testCase->run(!$parallel); } catch (TestCaseException $e) { $this->out('s'); $skipped[] = array($testCase->getName(), $entry, $e->getMessage()); } } if (count($running) > 1) { usleep(self::RUN_USLEEP); // stream_select() doesn't work with proc_open() } foreach ($running as $entry => $testCase) { if ($testCase->isReady()) { try { $testCase->collect(); $this->out('.'); $passed[] = array($testCase->getName(), $entry); } catch (TestCaseException $e) { if ($e->getCode() === TestCaseException::SKIPPED) { $this->out('s'); $skipped[] = array($testCase->getName(), $entry, $e->getMessage()); } else { $this->out('F'); $failed[] = array($testCase->getName(), $entry, $e->getMessage()); } } unset($running[$entry]); } } } $failedCount = count($failed); $skippedCount = count($skipped); if ($this->displaySkipped && $skippedCount) { $this->out("\n\nSkipped:\n"); foreach ($skipped as $i => $item) { list($name, $file, $message) = $item; $this->out("\n" . ($i + 1) . ") {$name}\n {$message}\n {$file}\n"); } } if (!$count) { $this->out("No tests found\n"); } elseif ($failedCount) { $this->out("\n\nFailures:\n"); foreach ($failed as $item) { list($name, $file, $message) = $item; $this->out("\n-> {$name}\n file: {$file}\n {$message}\n"); } $this->out("\nFAILURES! ({$count} tests, {$failedCount} failures, {$skippedCount} skipped)\n"); return FALSE; } else { $this->out("\n\nOK ({$count} tests, {$skippedCount} skipped)\n"); } return TRUE; }