Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
11b7a4d
Issue #KANWEBS-4141: Added the repeat option.
Apr 19, 2016
801c508
Issue #KANWEBS-4141: allow tests to be repeated
harizanov-angel May 25, 2016
9d67917
Issue #KANWEBS-4141: add support for the --only-repeat-failed option
harizanov-angel May 26, 2016
c024881
Issue #KANWEBS-4141: Added the repeat option.
Apr 19, 2016
c7dc36d
Issue #KANWEBS-4141: allow tests to be repeated
harizanov-angel May 25, 2016
6eb67d0
Put the default repeat value to 1 instead of 0.
PieterDC Jun 21, 2016
7297e94
Minor grammar and coding standard fixes.
PieterDC Jun 21, 2016
be6c4bc
Issue #KANWEBS-4865: Use testMethods when using repeat-only.
MaartenElsen Jul 11, 2016
e366d22
Show Skipped tests in ReaderFeedback even when repeat-only-failed is …
Jul 12, 2016
565b12e
Added tests for repeat options and skipped test display
Jul 13, 2016
f37c0d8
Merge branch 'repeat' into only-repeat-failed
PieterDC Jul 18, 2016
0898cf5
Adapt test to the new default - aligning it with that same option in …
PieterDC Jul 18, 2016
36c5e19
Merge remote-tracking branch 'upstream/master' into only-repeat-failed
PieterDC Jul 19, 2016
dc2c7a2
Adapt test to the new default - aligning it with that same option in …
PieterDC Jul 19, 2016
7da41b7
The new input option has to be reflected in the ParaTestCommandTest.
PieterDC Jul 19, 2016
ac24523
The complete method has to be in place and public in WrapperRunner an…
PieterDC Jul 19, 2016
7ddbcf2
Restore the complete() call from within Runner's run() method.
PieterDC Jul 19, 2016
b009332
Merge branch 'repeat' into only-repeat-failed
PieterDC Jul 19, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/ParaTest/Console/Commands/ParaTestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ protected function configure()
->addOption('coverage-html', null, InputOption::VALUE_REQUIRED, 'Generate code coverage report in HTML format.')
->addOption('coverage-php', null, InputOption::VALUE_REQUIRED, 'Serialize PHP_CodeCoverage object to file.')
->addOption('max-batch-size', 'm', InputOption::VALUE_REQUIRED, 'Max batch size (only for functional mode).', 0)
->addOption('filter', null, InputOption::VALUE_REQUIRED, 'Filter (only for functional mode).');
->addOption('filter', null, InputOption::VALUE_REQUIRED, 'Filter (only for functional mode).')
->addOption('repeat', null, InputOption::VALUE_REQUIRED, 'Runs the test(s) repeatedly.', 1)
->addOption('only-repeat-failed', null, InputOption::VALUE_NONE, 'Repeat only failing tests.', null);


if (self::isWhitelistSupported()) {
$this->addOption('whitelist', null, InputOption::VALUE_REQUIRED, 'Directory to add to the coverage whitelist.');
Expand Down
17 changes: 14 additions & 3 deletions src/ParaTest/Console/Testers/PHPUnit.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php
<?php
namespace ParaTest\Console\Testers;

use Symfony\Component\Console\Command\Command;
Expand Down Expand Up @@ -80,8 +80,19 @@ public function execute(InputInterface $input, OutputInterface $output)
$runner = new Runner($this->getRunnerOptions($input));
}

$runner->run();
return $runner->getExitCode();
// Allow the tests to be repeated.
$statusCode = 0;
$repeat = $input->getOption('repeat') ?: 1;
for ($i = 0; $i < $repeat; $i++) {
$runner->run();
$status = $runner->getExitCode();
$statusCode = $status ? $status : $statusCode;
}

// Print all messages at the end.
$runner->complete();

return $statusCode;
}

/**
Expand Down
34 changes: 32 additions & 2 deletions src/ParaTest/Runners/PHPUnit/BaseRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ abstract class BaseRunner
*/
protected $running = array();

/**
* A collection of ExecutableTest objects that have already been completed
* and were successful.
*
* @var array
*/
public $succeeded = array();

/**
* A tallied exit code that returns the highest exit
* code returned out of the entire collection of tests
Expand All @@ -56,6 +64,13 @@ abstract class BaseRunner
*/
protected $coverage = null;

/**
* Indicates whether the starting messages were printed or not.
*
* @var bool
*/
protected $starting_messages_printed = false;


public function __construct($opts = array())
{
Expand All @@ -69,7 +84,12 @@ public function run()
$this->verifyConfiguration();
$this->initCoverage();
$this->load();
$this->printer->start($this->options);

// Print the starting messages only if they were not printed yet.
if (!$this->starting_messages_printed) {
$this->printer->start($this->options);
$this->starting_messages_printed = true;
}
}

/**
Expand All @@ -95,7 +115,17 @@ protected function load()
{
$loader = new SuiteLoader($this->options);
$loader->load($this->options->path);
$executables = $this->options->functional ? $loader->getTestMethods() : $loader->getSuites();
$executables = $this->options->functional || $this->options->only_repeat_failed ? $loader->getTestMethods() : $loader->getSuites();
// Skip successful tests.
if ($this->options->only_repeat_failed) {
foreach ($this->succeeded as $test) {
foreach ($executables as $key => $executable) {
if ($test->getPath() == $executable->getPath() && $test->getName() == $executable->getName()) {
unset($executables[$key]);
}
}
}
}
$this->pending = array_merge($this->pending, $executables);
foreach ($this->pending as $pending) {
$this->printer->addTest($pending);
Expand Down
24 changes: 22 additions & 2 deletions src/ParaTest/Runners/PHPUnit/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ class Options
*/
protected $filtered;

/**
* The number of times that a test needs to be repeated.
*
* @var int
*/
protected $repeat;

/**
* Whether or not should repeat only the failing tests.
*
* @var int
*/
protected $only_repeat_failed;

/**
* A collection of option values directly corresponding
* to certain annotations - i.e group
Expand All @@ -82,6 +96,8 @@ public function __construct($opts = array())
$this->testsuite = $opts['testsuite'];
$this->maxBatchSize = $opts['max-batch-size'];
$this->filter = $opts['filter'];
$this->repeat = $opts['repeat'];
$this->only_repeat_failed = $opts['only-repeat-failed'];

// we need to register that options if they are blank but do not get them as
// key with null value in $this->filtered as it will create problems for
Expand Down Expand Up @@ -133,7 +149,9 @@ protected static function defaults()
'colors' => false,
'testsuite' => '',
'max-batch-size' => 0,
'filter' => null
'filter' => null,
'repeat' => 1,
'only-repeat-failed' => 0,
);
}

Expand Down Expand Up @@ -196,7 +214,9 @@ protected function filterOptions($options)
'colors' => $this->colors,
'testsuite' => $this->testsuite,
'max-batch-size' => $this->maxBatchSize,
'filter' => $this->filter
'filter' => $this->filter,
'repeat' => $this->repeat,
'only-repeat-failed' => $this->only_repeat_failed,
));
if ($configuration = $this->getConfigurationPath($filtered)) {
$filtered['configuration'] = new Configuration($configuration);
Expand Down
2 changes: 1 addition & 1 deletion src/ParaTest/Runners/PHPUnit/ResultPrinter.php
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ protected function processReaderFeedback($reader, $expectedTestCount)
$this->printFeedbackItem($item);
}

if ($this->processSkipped) {
if (isset($this->processSkipped)) {
$this->printSkippedAndIncomplete($actualTestCount, $expectedTestCount);
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/ParaTest/Runners/PHPUnit/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ public function run()
parent::run();

while (count($this->running) || count($this->pending)) {
/** @var ExecutableTest $test */
foreach ($this->running as $key => $test) {
if (!$this->testIsStillRunning($test)) {
if ($test->getExitCode() === 0) {
$this->succeeded[] = $test;
}
unset($this->running[$key]);
$this->releaseToken($key);
}
Expand All @@ -46,7 +50,7 @@ public function run()
* logs any results to JUnit, and cleans up temporary
* files
*/
private function complete()
public function complete()
{
$this->printer->printResults();
$this->interpreter->rewind();
Expand Down
2 changes: 1 addition & 1 deletion src/ParaTest/Runners/PHPUnit/WrapperRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ private function streamsOf($workers)
return $streams;
}

private function complete()
public function complete()
{
$this->setExitCode();
$this->printer->printResults();
Expand Down
35 changes: 35 additions & 0 deletions test/fixtures/results/mixed-results-with-skipped.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="test/fixtures/tests/" tests="4" assertions="2" failures="1" errors="1" skipped="1" time="0.007625">
<testsuite name="UnitTestWithClassAnnotationTest" tests="2" assertions="2" failures="1" errors="0"
time="0.006109"
file="/home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithClassAnnotationTest.php">
<testcase name="testTruth" class="UnitTestWithClassAnnotationTest"
file="/home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithClassAnnotationTest.php"
line="10" assertions="1" time="0.001760"/>
<testcase name="testFalsehood" class="UnitTestWithClassAnnotationTest"
file="/home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithClassAnnotationTest.php"
line="18" assertions="1" time="0.001195">
<failure type="PHPUnit_Framework_ExpectationFailedException">
UnitTestWithClassAnnotationTest::testFalsehood
Failed asserting that true is false.

/home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithClassAnnotationTest.php:20
</failure>
</testcase>
</testsuite>
<testsuite name="UnitTestWithErrorTest"
file="/home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithErrorTest.php" tests="1"
assertions="0" failures="0" errors="1" time="0.000397">
<testcase name="testTruth" class="UnitTestWithErrorTest"
file="/home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithErrorTest.php"
line="10" assertions="0" time="0.000397">
<error type="Exception">UnitTestWithErrorTest::testTruth
Exception: Error!!!

/home/brian/Projects/parallel-phpunit/test/fixtures/tests/UnitTestWithErrorTest.php:12
</error>
</testcase>
</testsuite>
</testsuite>
</testsuites>
4 changes: 4 additions & 0 deletions test/functional/EmptyRunnerStub.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
*/
class EmptyRunnerStub extends \ParaTest\Runners\PHPUnit\BaseRunner
{
public function complete()
{
}

public function run()
{
echo "EXECUTED";
Expand Down
2 changes: 2 additions & 0 deletions test/unit/ParaTest/Console/Commands/ParaTestCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public function testConfiguredDefinitionWithPHPUnitTester()
new InputOption('testsuite', null, InputOption::VALUE_OPTIONAL, 'Filter which testsuite to run'),
new InputOption('max-batch-size', 'm', InputOption::VALUE_REQUIRED, 'Max batch size (only for functional mode).', 0),
new InputOption('filter', null, InputOption::VALUE_REQUIRED, 'Filter (only for functional mode).'),
new InputOption('repeat', null, InputOption::VALUE_REQUIRED, 'Runs the test(s) repeatedly.', 1),
new InputOption('only-repeat-failed', null, InputOption::VALUE_NONE, 'Repeat only failing tests.', null),
);
if (ParaTestCommand::isWhitelistSupported()) {
$options[] = new InputOption('whitelist', null, InputOption::VALUE_REQUIRED, 'Directory to add to the coverage whitelist.');
Expand Down
2 changes: 2 additions & 0 deletions test/unit/ParaTest/ResultTester.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ abstract class ResultTester extends \TestBase
protected $failureSuite;
protected $otherErrorSuite;
protected $mixedSuite;
protected $skippedSuite;
protected $passingSuite;
protected $dataProviderSuite;

Expand All @@ -18,6 +19,7 @@ public function setUp()
$this->otherErrorSuite = $this->getSuiteWithResult('single-werror2.xml', 1);
$this->failureSuite = $this->getSuiteWithResult('single-wfailure.xml', 3);
$this->mixedSuite = $this->getSuiteWithResult('mixed-results.xml', 7);
$this->skippedSuite = $this->getSuiteWithResult('mixed-results-with-skipped.xml', 4);
$this->passingSuite = $this->getSuiteWithResult('single-passing.xml', 3);
$this->dataProviderSuite = $this->getSuiteWithResult('data-provider-result.xml', 50);
}
Expand Down
7 changes: 6 additions & 1 deletion test/unit/ParaTest/Runners/PHPUnit/OptionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public function setUp()
'phpunit' => 'phpunit',
'functional' => true,
'group' => 'group1',
'bootstrap' => '/path/to/bootstrap'
'bootstrap' => '/path/to/bootstrap',
'repeat' => 2,
'only-repeat-failed' => true
);
$this->options = new Options($this->unfiltered);
$this->cleanUpConfigurations();
Expand Down Expand Up @@ -44,6 +46,9 @@ public function testDefaults()
$this->assertEmpty($options->path);
$this->assertEquals(PHPUNIT, $options->phpunit);
$this->assertFalse($options->functional);
$this->assertEquals(1, $options->repeat);
$this->assertEquals(0, $options->only_repeat_failed);

}

public function testConfigurationShouldReturnXmlIfConfigNotSpecifiedAndFileExistsInCwd()
Expand Down
9 changes: 9 additions & 0 deletions test/unit/ParaTest/Runners/PHPUnit/ResultPrinterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,15 @@ public function testPrintFeedbackForMixed()
$this->assertEquals('.F.E.F.', $contents);
}

public function testPrintFeedbackForSkipped()
{
$this->printer->addTest($this->skippedSuite);
ob_start();
$this->printer->printFeedback($this->skippedSuite);
$contents = ob_get_clean();
$this->assertEquals('.FES', $contents);
}

public function testPrintFeedbackForMoreThan100Suites()
{
//add tests
Expand Down