Last active
August 25, 2018 19:50
-
-
Save veproza/613dcffc82dcb30bb5e30065f30d6b6b to your computer and use it in GitHub Desktop.
TeamCity output including test duration for Nette Tester. Requires a custom Tester fork: https://github.com/veproza/tester (or just this commit: https://github.com/veproza/tester/commit/d3f4ad2c500d2b927eb372ec2be9b2f594bec9bc)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* By jiripudil, https://github.com/jiripudil/intellij-nette-tester/blob/master/resources/setup.php | |
* @license https://github.com/jiripudil/intellij-nette-tester/blob/master/LICENSE.md | |
*/ | |
use Tester\Runner\Runner; | |
final class TeamCityOutputHandler implements \Tester\Runner\StartAwareOutputHandler | |
{ | |
/** | |
* @var resource | |
*/ | |
private $file; | |
/** | |
* @var float[] | |
*/ | |
private $startTimes; | |
public function __construct($output = 'php://output') | |
{ | |
$this->file = \fopen($output, 'w'); | |
} | |
public function begin(): void | |
{ | |
// \fwrite($this->file, $this->message('testCount', array('count' => 0))); | |
} | |
function start(\Tester\Runner\Test $test): void | |
{ | |
$flowId = \md5($test->getSignature()); | |
$this->startTimes[$flowId] = microtime(TRUE); | |
$testName = $this->getTestName($test); | |
\fwrite($this->file, $this->message('testStarted', ['name' => $testName, 'flowId' => $flowId])); | |
} | |
function finish(\Tester\Runner\Test $test): void | |
{ | |
$testName = $this->getTestName($test); | |
$message = $test->message; | |
$flowId = \md5($test->getSignature()); | |
$durationMicros = microtime(TRUE) - $this->startTimes[$flowId]; | |
$duration = round($durationMicros * 1000); | |
if ($test->getResult() === \Tester\Runner\Test::SKIPPED) { | |
\fwrite($this->file, $this->message('testIgnored', ['name' => $testName, 'flowId' => $flowId, 'message' => 'Test skipped', 'details' => $message])); | |
} elseif ($test->getResult() === \Tester\Runner\Test::FAILED) { // Runner::FAILED, Test::FAILED | |
$extraArguments = []; | |
if (\preg_match("/^diff \"(.*)\" \"(.*)\"$/m", $message, $matches)) { // Windows build | |
$expectedFile = \str_replace('""', '"', $matches[1]); | |
$actualFile = \str_replace('""', '"', $matches[2]); | |
$extraArguments = ['type' => 'comparisonFailure', 'expectedFile' => $expectedFile, 'actualFile' => $actualFile]; | |
} elseif (\preg_match("/^diff '?(.*)'? '?(.*)'?$/m", $message, $matches)) { | |
$expectedFile = \trim($matches[1], "'"); | |
$actualFile = \trim($matches[2], "'"); | |
$extraArguments = ['type' => 'comparisonFailure', 'expectedFile' => $expectedFile, 'actualFile' => $actualFile]; | |
} elseif (\preg_match("/Failed: (.*) should be( equal to)?\s+\.*\s*(.*) in/is", $message, $matches)) { | |
$expected = $matches[3]; | |
$actual = $matches[1]; | |
$extraArguments = ['type' => 'comparisonFailure', 'expected' => $expected, 'actual' => $actual]; | |
} | |
$args = \array_merge([ | |
'name' => $testName, | |
'flowId' => $flowId, | |
'message' => 'Test failed', | |
'details' => $message, | |
'duration' => $duration, | |
], $extraArguments); | |
\fwrite($this->file, $this->message('testFailed', $args)); | |
} | |
\fwrite($this->file, $this->message('testFinished', ['name' => $testName, 'flowId' => $flowId, 'duration' => $duration])); | |
} | |
private function message($messageName, $args) | |
{ | |
$argsPairs = []; | |
foreach ($args as $arg => $value) { | |
$argsPairs[] = \sprintf("%s='%s'", $arg, $this->escape($value)); | |
} | |
return \sprintf( | |
"##teamcity[%s %s]\n\n", | |
$messageName, | |
\implode(' ', $argsPairs) | |
); | |
} | |
private function escape($value) | |
{ | |
$replace = [ | |
"|" => "||", | |
"'" => "|'", | |
"\n" => "|n", | |
"\r" => "|r", | |
"]" => "|]", | |
"[" => "|[", | |
]; | |
return \strtr($value, $replace); | |
} | |
public function end(): void | |
{ | |
} | |
function prepare(\Tester\Runner\Test $test): void | |
{ | |
// noop | |
} | |
/** | |
* @param \Tester\Runner\Test $test | |
* @return null|string | |
*/ | |
private function getTestName(\Tester\Runner\Test $test) | |
{ | |
return $test->title | |
? $test->title | |
: str_replace(__DIR__ . DIRECTORY_SEPARATOR, '', $test->getFile()); | |
} | |
} | |
/** @var Runner $runner */ | |
// replace registered output handlers with TC | |
$runner->outputHandlers = [new TeamCityOutputHandler()]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment