diff --git a/src/ParaTest/Console/Testers/PHPUnit.php b/src/ParaTest/Console/Testers/PHPUnit.php index a851abf0..81cc2cd5 100644 --- a/src/ParaTest/Console/Testers/PHPUnit.php +++ b/src/ParaTest/Console/Testers/PHPUnit.php @@ -43,6 +43,7 @@ public function configure(Command $command) ->addOption('stop-on-failure', null, InputOption::VALUE_NONE, 'Don\'t start any more processes after a failure.') ->addOption('log-junit', null, InputOption::VALUE_REQUIRED, 'Log test execution in JUnit XML format to file.') ->addOption('colors', null, InputOption::VALUE_NONE, 'Displays a colored bar as a test result.') + ->addOption('testsuite', null, InputOption::VALUE_OPTIONAL, 'Filter which testsuite to run') ->addArgument('path', InputArgument::OPTIONAL, 'The path to a directory or file containing tests. (default: current directory)') ->addOption('path', null, InputOption::VALUE_REQUIRED, 'An alias for the path argument.'); $this->command = $command; diff --git a/src/ParaTest/Runners/PHPUnit/Configuration.php b/src/ParaTest/Runners/PHPUnit/Configuration.php index 2536ffe3..60bdb439 100644 --- a/src/ParaTest/Runners/PHPUnit/Configuration.php +++ b/src/ParaTest/Runners/PHPUnit/Configuration.php @@ -90,6 +90,32 @@ public function getSuites() return $suites; } + public function getTestsuiteItems() + { + + } + + /** + * @param string $suiteName + * + * @return array|null + */ + public function getSuiteFiles($suiteName) + { + $nodes = $this->xml->xpath(sprintf('//testsuite[@name="%s"]', $suiteName)); + + $files = array(); + while (list(, $node) = each($nodes)) { + foreach ($node->file as $file) { + foreach ($this->getSuitePaths((string) $file) as $path) { + $files[] = $path; + } + } + } + + return $files; + } + /** * Return the path of the directory * that contains the phpunit configuration diff --git a/src/ParaTest/Runners/PHPUnit/Options.php b/src/ParaTest/Runners/PHPUnit/Options.php index 59db70f4..12b15bc9 100644 --- a/src/ParaTest/Runners/PHPUnit/Options.php +++ b/src/ParaTest/Runners/PHPUnit/Options.php @@ -79,6 +79,7 @@ public function __construct($opts = array()) $this->runner = $opts['runner']; $this->noTestTokens = $opts['no-test-tokens']; $this->colors = $opts['colors']; + $this->testsuite = $opts['testsuite']; $this->filtered = $this->filterOptions($opts); $this->initAnnotations(); @@ -112,6 +113,7 @@ protected static function defaults() 'runner' => 'Runner', 'no-test-tokens' => false, 'colors' => false, + 'testsuite' => '', ); } @@ -172,6 +174,7 @@ protected function filterOptions($options) 'runner' => $this->runner, 'no-test-tokens' => $this->noTestTokens, 'colors' => $this->colors, + 'testsuite' => $this->testsuite )); if ($configuration = $this->getConfigurationPath($filtered)) { $filtered['configuration'] = new Configuration($configuration); diff --git a/src/ParaTest/Runners/PHPUnit/SuiteLoader.php b/src/ParaTest/Runners/PHPUnit/SuiteLoader.php index 694fe8c3..24aa79e1 100644 --- a/src/ParaTest/Runners/PHPUnit/SuiteLoader.php +++ b/src/ParaTest/Runners/PHPUnit/SuiteLoader.php @@ -92,6 +92,16 @@ public function load($path = '') if ($path) { $this->loadPath($path); + } elseif (isset($this->options->testsuite) && $this->options->testsuite) { + foreach ($configuration->getSuiteFiles($this->options->testsuite) as $file) { + $this->loadFile($file); + } + foreach ($configuration->getSuites() as $suite) { + foreach ($suite as $suitePath) { + $this->loadPath($suitePath); + } + } + $this->files = array_unique($this->files); // remove duplicates } elseif ($suites = $configuration->getSuites()) { foreach ($suites as $suite) { foreach ($suite as $suitePath) { diff --git a/test/fixtures/phpunit-file.xml b/test/fixtures/phpunit-file.xml new file mode 100644 index 00000000..4ec508b1 --- /dev/null +++ b/test/fixtures/phpunit-file.xml @@ -0,0 +1,18 @@ + + + + + ./passing-tests/GroupsTest.php + + + diff --git a/test/fixtures/phpunit-files-dirs-mix-duplicates.xml b/test/fixtures/phpunit-files-dirs-mix-duplicates.xml new file mode 100644 index 00000000..0a46c39b --- /dev/null +++ b/test/fixtures/phpunit-files-dirs-mix-duplicates.xml @@ -0,0 +1,20 @@ + + + + + ./passing-tests/ + ./passing-tests/TestOfUnits.php + ./passing-tests/GroupsTest.php + + + diff --git a/test/fixtures/phpunit-files-dirs-mix.xml b/test/fixtures/phpunit-files-dirs-mix.xml new file mode 100644 index 00000000..e601aef6 --- /dev/null +++ b/test/fixtures/phpunit-files-dirs-mix.xml @@ -0,0 +1,20 @@ + + + + + ./failing-tests/ + ./passing-tests/TestOfUnits.php + ./passing-tests/GroupsTest.php + + + diff --git a/test/fixtures/phpunit-multifile.xml b/test/fixtures/phpunit-multifile.xml new file mode 100644 index 00000000..4e8449dd --- /dev/null +++ b/test/fixtures/phpunit-multifile.xml @@ -0,0 +1,19 @@ + + + + + ./passing-tests/TestOfUnits.php + ./passing-tests/GroupsTest.php + + + diff --git a/test/unit/ParaTest/Console/Commands/ParaTestCommandTest.php b/test/unit/ParaTest/Console/Commands/ParaTestCommandTest.php index 13323bc1..c11e62cc 100644 --- a/test/unit/ParaTest/Console/Commands/ParaTestCommandTest.php +++ b/test/unit/ParaTest/Console/Commands/ParaTestCommandTest.php @@ -46,7 +46,8 @@ public function testConfiguredDefinitionWithPHPUnitTester() new InputOption('path', null, InputOption::VALUE_REQUIRED, 'An alias for the path argument.'), new InputOption('coverage-clover', null, InputOption::VALUE_REQUIRED, 'Generate code coverage report in Clover XML format.'), new InputOption('coverage-html', null, InputOption::VALUE_REQUIRED, 'Generate code coverage report in HTML format.'), - new InputOption('coverage-php', null, InputOption::VALUE_REQUIRED, 'Serialize PHP_CodeCoverage object to file.') + new InputOption('coverage-php', null, InputOption::VALUE_REQUIRED, 'Serialize PHP_CodeCoverage object to file.'), + new InputOption('testsuite', null, InputOption::VALUE_OPTIONAL, 'Filter which testsuite to run') )); $definition = $this->command->getDefinition(); $this->assertEquals($expected, $definition); diff --git a/test/unit/ParaTest/Console/Testers/PHPUnitTest.php b/test/unit/ParaTest/Console/Testers/PHPUnitTest.php index 2450e760..4427981c 100644 --- a/test/unit/ParaTest/Console/Testers/PHPUnitTest.php +++ b/test/unit/ParaTest/Console/Testers/PHPUnitTest.php @@ -22,7 +22,8 @@ public function testConfigureAddsOptionsAndArgumentsToCommand() new InputOption('log-junit', null, InputOption::VALUE_REQUIRED, 'Log test execution in JUnit XML format to file.'), new InputOption('colors', null, InputOption::VALUE_NONE, 'Displays a colored bar as a test result.'), new InputArgument('path', InputArgument::OPTIONAL, 'The path to a directory or file containing tests. (default: current directory)'), - new InputOption('path', null, InputOption::VALUE_REQUIRED, 'An alias for the path argument.') + new InputOption('path', null, InputOption::VALUE_REQUIRED, 'An alias for the path argument.'), + new InputOption('testsuite', null, InputOption::VALUE_OPTIONAL, 'Filter which testsuite to run') )); $tester = new PHPUnit(); $tester->configure($testCommand); diff --git a/test/unit/ParaTest/Runners/PHPUnit/SuiteLoaderTest.php b/test/unit/ParaTest/Runners/PHPUnit/SuiteLoaderTest.php index 653db4fe..dba1fd7e 100644 --- a/test/unit/ParaTest/Runners/PHPUnit/SuiteLoaderTest.php +++ b/test/unit/ParaTest/Runners/PHPUnit/SuiteLoaderTest.php @@ -42,6 +42,77 @@ public function testLoadBarePathWithNoPathAndNoConfiguration() $loader->load(); } + public function testLoadTestsuiteFileFromConfig() + { + $options = new Options( + array('configuration' => $this->fixture('phpunit-file.xml'), 'testsuite' => 'ParaTest Fixtures') + ); + $loader = new SuiteLoader($options); + $loader->load(); + $files = $this->getObjectValue($loader, 'files'); + + $expected = 1; + $this->assertEquals($expected, sizeof($files)); + } + + public function testLoadTestsuiteFilesFromConfig() + { + $options = new Options( + array('configuration' => $this->fixture('phpunit-multifile.xml'), 'testsuite' => 'ParaTest Fixtures') + ); + $loader = new SuiteLoader($options); + $loader->load(); + $files = $this->getObjectValue($loader, 'files'); + + $expected = 2; + $this->assertEquals($expected, sizeof($files)); + } + + public function testLoadTestsuiteWithDirectory() + { + $options = new Options(array('configuration' => $this->fixture('phpunit-passing.xml'), 'testsuite' => 'ParaTest Fixtures')); + $loader = new SuiteLoader($options); + $loader->load(); + $files = $this->getObjectValue($loader, 'files'); + + $expected = sizeof($this->findTests(FIXTURES . DS . 'passing-tests')); + $this->assertEquals($expected, sizeof($files)); + } + + public function testLoadTestsuiteWithDirectories() + { + $options = new Options(array('configuration' => $this->fixture('phpunit-multidir.xml'), 'testsuite' => 'ParaTest Fixtures')); + $loader = new SuiteLoader($options); + $loader->load(); + $files = $this->getObjectValue($loader, 'files'); + + $expected = sizeof($this->findTests(FIXTURES . DS . 'passing-tests')) + + sizeof($this->findTests(FIXTURES . DS . 'failing-tests')); + $this->assertEquals($expected, sizeof($files)); + } + + public function testLoadTestsuiteWithFilesDirsMixed() + { + $options = new Options(array('configuration' => $this->fixture('phpunit-files-dirs-mix.xml'), 'testsuite' => 'ParaTest Fixtures')); + $loader = new SuiteLoader($options); + $loader->load(); + $files = $this->getObjectValue($loader, 'files'); + + $expected = sizeof($this->findTests(FIXTURES . DS . 'failing-tests')) + 2; + $this->assertEquals($expected, sizeof($files)); + } + + public function testLoadTestsuiteWithDuplicateFilesDirMixed() + { + $options = new Options(array('configuration' => $this->fixture('phpunit-files-dirs-mix-duplicates.xml'), 'testsuite' => 'ParaTest Fixtures')); + $loader = new SuiteLoader($options); + $loader->load(); + $files = $this->getObjectValue($loader, 'files'); + + $expected = sizeof($this->findTests(FIXTURES . DS . 'passing-tests')) + 1; + $this->assertEquals($expected, sizeof($files)); + } + public function testLoadSuiteFromConfig() { $options = new Options(array('configuration' => $this->fixture('phpunit-passing.xml'))); @@ -83,6 +154,15 @@ public function testLoadFileGetsPathOfFile() $this->assertEquals($path, array_shift($paths)); } + protected function getLoadedPaths($path, $loader=null) + { + $loader = $loader ?: new SuiteLoader(); + $loader->load($path); + $loaded = $this->getObjectValue($loader, 'loadedSuites'); + $paths = array_keys($loaded); + return $paths; + } + public function testLoadFileShouldLoadFileWhereNameDoesNotEndInTest() { $path = $this->fixture('passing-tests/TestOfUnits.php'); @@ -118,6 +198,16 @@ public function testFirstParallelSuiteHasCorrectFunctions($paraSuites) $this->assertEquals('testAddition', $functions[4]->getName()); } + private function suiteByPath($path, array $paraSuites) + { + foreach ($paraSuites as $completePath => $suite) { + if (strstr($completePath, $path)) { + return $suite; + } + } + throw new \RuntimeException("Suite $path not found."); + } + /** * @depends testLoadDirGetsPathOfAllTestsWithKeys */ @@ -161,23 +251,4 @@ public function testExecutableTestsForFunctionalModeUse() $testMethodName = $this->getObjectValue($testMethod, 'name'); $this->assertEquals($testMethodName, 'testTwoA|testTwoBDependsOnA'); } - - protected function getLoadedPaths($path, $loader=null) - { - $loader = $loader ?: new SuiteLoader(); - $loader->load($path); - $loaded = $this->getObjectValue($loader, 'loadedSuites'); - $paths = array_keys($loaded); - return $paths; - } - - private function suiteByPath($path, array $paraSuites) - { - foreach ($paraSuites as $completePath => $suite) { - if (strstr($completePath, $path)) { - return $suite; - } - } - throw new \RuntimeException("Suite $path not found."); - } }