Skip to content
This repository has been archived by the owner on Mar 30, 2018. It is now read-only.

Commit

Permalink
Switch output dependency from TAP to Teamcity (#237)
Browse files Browse the repository at this point in the history
- Initial conversion from depending on TAP output. Switches to Teamcity output.
- Skip AllTests test when < PHPUnit 6 (fail here is a PHPUnit bug ignoring ---teamcity flag)
Checkout output on all scenarios just to be sure nothing else bugs out the output
  • Loading branch information
padraic authored and theofidry committed May 30, 2017
1 parent 026dad1 commit 326371f
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 93 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"require": {
"php": ">=5.6.0",
"phpunit/phpunit": "^5.0",
"phpunit/phpunit": "^5.7",
"symfony/console": "^2.6|^3.0",
"symfony/finder": "^2.6|^3.0",
"symfony/process": "^2.6|^3.0",
Expand All @@ -29,7 +29,7 @@
},
"require-dev": {
"mockery/mockery": "^0.9",
"behat/behat": "^3.0.15",
"behat/behat": "^3.3",
"symfony/filesystem": "^2.6|^3.0",
"mikey179/vfsStream": "^1.4",
"ciaranmcnulty/versionbasedtestskipper": "^0.2.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,5 @@ Feature: Use Humbug
When I run humbug
Then I should see output containing:
"""
Humbug running test suite to generate logs and code coverage data...
Tests must be in a fully passing state before Humbug is run.
Incomplete, skipped or risky tests are allowed.
The testing framework reported an exit code of 143.
The testing framework ran into a failure or error. Refer to output below.
Stdout:
> TAP version 13
> not ok 1 - Error: FooTest::testAddsNumbers
Failure Message:
"""
17 changes: 5 additions & 12 deletions src/Adapter/AdapterAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

abstract class AdapterAbstract
{
protected $okCount = 0;

/**
* Runs the tests suite according to Runner set options and the execution
Expand Down Expand Up @@ -52,31 +53,23 @@ abstract public function getClassFile($class, Container $container);
*/
public function ok($output)
{
$lines = explode("\n", $output);
foreach ($lines as $line) {
if (preg_match("%not ok \\d+ - %", $line)
&& !preg_match("%# TODO%", $line)) {
return false;
}
}
return true;
return 0 === preg_match("%##teamcity\[testFailed%", $output);
}

/**
* Parse the test adapter result output and count ok results.
*
* This assumes the output is in Test Anywhere Protocol (TAP) format.
*
* TODO: Update regex to make certain we take the LAST numbered ok
*
* @param string $output
* @return bool|int
*/
public function hasOks($output)
{
$result = preg_match_all("%ok (\\d+) - .*%m", $output, $matches);
$result = preg_match_all("%##teamcity\[testFinished%", $output);
if ($result) {
return (int) end($matches[1]);
$this->okCount += $result;
return $this->okCount;
}
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Adapter/Phpunit.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function getProcess(
/**
* We like standardised easy to parse outout
*/
array_unshift($jobopts['command'], '--tap');
array_unshift($jobopts['command'], '--teamcity');

/*
* We only need a single fail!
Expand Down
10 changes: 1 addition & 9 deletions src/ProcessRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,11 @@ public function run(
&$hasFailure
) {
if ($out == Process::ERR) {
$hasFailure= true;
$process->stop();
return;
}

if ($hasFailure) {
return;
$hasFailure = true;
}

if (!$testFrameworkAdapter->ok($data)) {
$hasFailure = true;
$process->stop();
return;
}

$oksCount = $testFrameworkAdapter->hasOks($data);
Expand Down
43 changes: 29 additions & 14 deletions src/Renderer/Text.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function renderInitialRunFail(TestSuiteResult $result)
}
if ($result->hasStdOut()) {
$error[] = 'Stdout:';
$error = array_merge($error, $this->indent($this->headAndTail($result->getStdOut()), true));
$error = array_merge($error, $this->indent($this->extractFail($result->getStdOut()), true));
}
if ($result->hasStdErr()) {
$error[] = 'Stderr:';
Expand Down Expand Up @@ -287,7 +287,7 @@ public function renderLogToText($log)
* @param bool $asArray
* @return string
*/
protected function indent($output, $asArray = false)
private function indent($output, $asArray = false)
{
$lines = explode("\n", $output);
$out = [];
Expand All @@ -302,22 +302,37 @@ protected function indent($output, $asArray = false)
}

/**
* Display only the head and tail of given output, removing text between
* the two where deemed umimportant.
* Extract failure details and reformat into human readable form.
*
* @param string $output
* @param string $output
* @return string
*/
protected function headAndTail($output, $lineCount = 20, $omittedMarker = '[...Middle of output removed by Humbug...]')
private function extractFail($output)
{
$lines = explode("\n", $output);
if (count($lines) <= ($lineCount * 2)) {
return $output;
if (preg_match('%##teamcity\[testFailed.*\]%', $output, $matches)) {
preg_match(
"/##teamcity\\[testFailed.*name='(.*)' message='(.*)' details='\\s*(.*)' flowId=.*/",
$output,
$matches
);
$matches = $this->replaceEscapedChars($matches);
$fail = sprintf(
'Test Name: %s' . PHP_EOL . 'Failure Message: %s' . PHP_EOL . 'Trace:' . PHP_EOL . '%s',
$matches[1],
$matches[2],
$matches[3]
);
return $fail;
}
return implode("\n", array_merge(
array_slice($lines, 0, $lineCount),
[$omittedMarker],
array_slice($lines, -$lineCount, $lineCount)
));
return 'No failure output was detected by Humbug, but a failure was reported by PHPUnit.';
}

private function replaceEscapedChars(array $chars)
{
return str_replace(
["|n ", "|n", "|'", "|\""],
["\n", "\n", "'", "\""],
$chars
);
}
}
38 changes: 7 additions & 31 deletions tests/Adapter/PhpunitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,35 +88,7 @@ public function testAdapterRunsDefaultPhpunitCommand()

$result = $process->getOutput();

$this->assertStringStartsWith('TAP version', $result, $process->getErrorOutput());
$this->assertTrue($adapter->ok($result));
}

public function testAdapterRunsPhpunitCommandWithAlltestsFileTarget()
{
$container = m::mock('\Humbug\Container');
$container->shouldReceive([
'getSourceList' => __DIR__ . '/_files/phpunit2',
'getTestRunDirectory' => __DIR__ . '/_files/phpunit2',
'getBaseDirectory' => __DIR__ . '/_files/phpunit2',
'getTimeout' => 1200,
'getTempDirectory' => $this->tmpDir,
'getAdapterOptions' => [],
'getBootstrap' => '',
'getAdapterConstraints' => 'AllTests.php'
]);

$adapter = new Phpunit;
$process = $adapter->getProcess(
$container,
true,
true
);
$process->run();

$result = $process->getOutput();

$this->assertStringStartsWith('TAP version', $result, $process->getErrorOutput());
$this->assertContains('##teamcity[', $result, $process->getErrorOutput());
$this->assertTrue($adapter->ok($result));
}

Expand Down Expand Up @@ -171,6 +143,7 @@ public function testAdapterDetectsTestsFailingFromTestFail()

$result = $process->getOutput();

$this->assertContains('##teamcity[', $result);
$this->assertFalse($adapter->ok($result), $process->getErrorOutput());
}

Expand Down Expand Up @@ -198,6 +171,7 @@ public function testAdapterDetectsTestsFailingFromException()

$result = $process->getOutput();

$this->assertContains('##teamcity[', $result);
$this->assertFalse($adapter->ok($result), $process->getErrorOutput());
}

Expand Down Expand Up @@ -225,11 +199,13 @@ public function testAdapterDetectsTestsFailingFromError()

$result = $process->getOutput();

$this->assertContains('##teamcity[', $result);
$this->assertFalse($adapter->ok($result), $process->getErrorOutput());
}

public function testAdapterOutputProcessingDetectsFailOverMultipleLinesWithNoDepOnFinalStatusReport()
{
$this->markTestIncomplete('This seems redundant as it should never happen - fail on first failure is set');
$adapter = new Phpunit;
$output = <<<OUTPUT
TAP version 13
Expand Down Expand Up @@ -271,9 +247,9 @@ public function testShouldNotNotifyRegressionWhileRunningProcess($directory)
$process->run();

$result = $process->getOutput();

$this->assertEquals(2, $adapter->hasOks($result), $process->getErrorOutput());
$this->assertStringStartsWith('TAP version', $result);
$this->assertContains('##teamcity[', $result);
$this->assertTrue($adapter->ok($result), "Regression output: \n" . $result);
}

Expand Down
4 changes: 3 additions & 1 deletion tests/Adapter/_files/phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

<filter>
<whitelist>
<directory>.</directory>
<exclude>
<directory>.</directory>
</exclude>
</whitelist>
</filter>

Expand Down
4 changes: 3 additions & 1 deletion tests/Adapter/_files/phpunit2/phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

<filter>
<whitelist>
<directory>.</directory>
<exclude>
<directory>.</directory>
</exclude>
</whitelist>
</filter>

Expand Down
10 changes: 8 additions & 2 deletions tests/Adapter/_files/regression/server-argv/phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,11 @@
<directory>.</directory>
</testsuite>
</testsuites>

</phpunit>
<filter>
<whitelist>
<exclude>
<directory>.</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
7 changes: 7 additions & 0 deletions tests/Adapter/_files/regression/wildcard-dirs/phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,12 @@
<directory>./*/Tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<exclude>
<directory>.</directory>
</exclude>
</whitelist>
</filter>

</phpunit>
13 changes: 2 additions & 11 deletions tests/ProcessRunnerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,7 @@ public function testShouldInvokeOnProgressCallback()
private function createOkProcess()
{
$process = new PhpProcess('<?php
echo "TAP version 13\r\n";
echo "ok 78 - Humbug\Test\Mutator\ConditionalBoundary\LessThanOrEqualToTest::testReturnsTokenEquivalentToLessThanOrEqualTo\r\n";
echo "ok 79 - Humbug\Test\Mutator\ConditionalBoundary\LessThanOrEqualToTest::testMutatesLessThanToLessThanOrEqualTo\r\n";
echo "ok 80 - Humbug\Test\Mutator\ConditionalBoundary\LessThanTest::testReturnsTokenEquivalentToLessThanOrEqualTo\r\n";
echo "##teamcity[testFinished name=\'Some sort of test finished\' duration=\'0\' flowId=\'15199\']\r\n";
');

return $process;
Expand All @@ -95,13 +92,7 @@ private function runProcess(PhpProcess $process, $onProgressCallback = null)
private function createNotOkProcess()
{
$process = new PhpProcess('<?php
echo "TAP version 13\r\n";
echo "not ok 82 - Humbug\Test\Mutator\ConditionalBoundary\LessThanOrEqualToTest::testMutatesLessThanToLessThanOrEqualTo\r\n";
echo "not ok 78 - Humbug\Test\Mutator\ConditionalBoundary\LessThanOrEqualToTest::testReturnsTokenEquivalentToLessThanOrEqualTo\r\n";
echo "not ok 79 - Humbug\Test\Mutator\ConditionalBoundary\LessThanOrEqualToTest::testMutatesLessThanToLessThanOrEqualTo\r\n";
echo "not ok 80 - Humbug\Test\Mutator\ConditionalBoundary\LessThanOrEqualToTest::testMutatesLessThanToLessThanOrEqualTo\r\n";
echo "not ok 81 - Humbug\Test\Mutator\ConditionalBoundary\LessThanOrEqualToTest::testMutatesLessThanToLessThanOrEqualTo\r\n";
echo "ok 81 - Humbug\Test\Mutator\ConditionalBoundary\LessThanOrEqualToTest::testMutatesLessThanToLessThanOrEqualTo\r\n";
echo "##teamcity[testFailed name=\'Some sort of test finished\' duration=\'0\' flowId=\'15199\']\r\n";
');
return $process;
}
Expand Down

0 comments on commit 326371f

Please sign in to comment.