Skip to content

Commit

Permalink
Group loader fixes (#96)
Browse files Browse the repository at this point in the history
* fixed loading groups in filter

* make all tasks to return results

* added warning that relative path not set

* fixed codestyle
  • Loading branch information
DavertMik authored Dec 18, 2021
1 parent ca1650e commit 616747b
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 24 deletions.
38 changes: 33 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,39 @@ So we prepared a set of predefined Robo tasks that can be combined and reconfigu
Load tests from a folder and distributes them between groups.

```php
$this->taskSplitTestsByGroups(5)
$result = $this->taskSplitTestsByGroups(5)
->testsFrom('tests/acceptance')
->projectRoot('.')
->groupsTo('tests/_data/group_')
->run();

// task returns a result which contains information about processed data:
// optionally check result data
if ($result->wasSuccessful()) {
$groups = $result['groups'];
$tests = $result['tests'];
$filenames = $result['files'];
}
```

this command uses `Codeception\Test\Loader` to load tests and organize them between group. If you want just split test file and not actual tests (and not load tests into memory) you can use:
> This command **loads Codeception into memory**, loads and parses tests to organize them between group. If you want just split test file and not actual tests (and not load tests into memory) use `taskSplitTestFilesByGroups`:
### SplitTestFilesByGroups

To split tests by suites (files) without loading them into memory use `taskSplitTestFilesByGroups` method:

```php
$this->taskSplitTestFilesByGroups(5)
$result = $this->taskSplitTestFilesByGroups(5)
->testsFrom('tests')
->groupsTo('tests/_data/paratest_')
->run();

// optionally check result data
if ($result->wasSuccessful()) {
$filenames = $result['files'];
}
```

### SplitTestsByTime

Enable extension for collect execution time of you use taskSplitTestsByTime
Expand All @@ -70,11 +88,16 @@ extensions:
Load tests from a folder and distributes them between groups by execution time.

```php
$this->taskSplitTestsByTime(5)
$result = $this->taskSplitTestsByTime(5)
->testsFrom('tests/acceptance')
->projectRoot('.')
->groupsTo('tests/_data/group_')
->run();

// optionally check result data
if ($result->wasSuccessful()) {
$filenames = $result['files'];
}
```

this command need run all tests with `Codeception\Task\TimeReporter` for collect execution time. If you want just split tests between group (and not execute its) you can use SplitTestsByGroups. **Please be aware**: This task will not consider any 'depends' annotation!
Expand All @@ -100,11 +123,16 @@ $this->taskMergeFailedTestsReports()

Load the failed Tests from a reportfile into the groups:
```php
$this
$result = $this
->taskSplitFailedTests(5)
->setReportPath(\Codeception\Configuration::outputDir() . 'failedTests.txt') // absoulute Path to Reportfile
->groupsTo(\Codeception\Configuration::outputDir() . 'group_')
->run();

// optionally check result data
if ($result->wasSuccessful()) {
$filenames = $result['files'];
}
```

### MergeXmlReports
Expand Down
12 changes: 8 additions & 4 deletions src/Filter/GroupFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Codeception\Task\Filter;

use Codeception\Lib\GroupManager;
use Codeception\Test\Descriptor as TestDescriptor;
use Codeception\Util\Annotation;
use InvalidArgumentException;
Expand Down Expand Up @@ -123,24 +124,27 @@ public function setTests(array $tests): void
*/
public function filter(): array
{
$groupManager = new GroupManager([]);

$testsByGroups = [];
foreach ($this->getTests() as $test) {
if (!($test instanceof SelfDescribing)) {
throw new InvalidArgumentException(
'Tests must be an instance of ' . SelfDescribing::class
);
}
[$class, $method] = explode(':', TestDescriptor::getTestSignature($test));
$annotations = Annotation::forMethod($class, $method)->fetchAll('group');

$groups = $groupManager->groupsForTest($test);

if (
!empty($this->getExcludedGroups())
&& [] === array_diff($this->getExcludedGroups(), $annotations)
&& [] === array_diff($this->getExcludedGroups(), $groups)
) {
continue;
}
if (
!empty($this->getIncludedGroups())
&& [] !== array_diff($this->getIncludedGroups(), $annotations)
&& [] !== array_diff($this->getIncludedGroups(), $groups)
) {
continue;
}
Expand Down
11 changes: 9 additions & 2 deletions src/Splitter/FailedTestSplitterTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Codeception\Task\Splitter;

use InvalidArgumentException;
use Robo\Result;
use RuntimeException;

class FailedTestSplitterTask extends TestsSplitter
Expand All @@ -23,7 +24,7 @@ public function getReportPath(): string
/**
* @inheritDoc
*/
public function run()
public function run(): Result
{
$this->claimCodeceptionLoaded();
$reportPath = $this->getReportPath();
Expand All @@ -34,14 +35,20 @@ public function run()
);
}

$this->splitToGroupFiles(
$filenames = $this->splitToGroupFiles(
$this->filter(
explode(
PHP_EOL,
file_get_contents($reportPath)
)
)
);

$numFiles = count($filenames);

return Result::success($this, "Split all tests into $numFiles group files", [
'files' => $filenames,
]);
}

/**
Expand Down
11 changes: 10 additions & 1 deletion src/Splitter/SplitTestsByTimeTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use JsonException;
use PHPUnit\Framework\DataProviderTestSuite;
use Robo\Exception\TaskException;
use Robo\Result;
use RuntimeException;

/**
Expand All @@ -25,7 +26,7 @@ public function statFile(string $path): self
return $this;
}

public function run(): void
public function run(): Result
{
$this->claimCodeceptionLoaded();

Expand Down Expand Up @@ -70,6 +71,7 @@ public function run(): void
$groups[$i]['sum'] += $time;
}

$filenames = [];
// saving group files
foreach ($groups as $i => ['tests' => $tests, 'sum' => $sum]) {
$filename = $this->saveTo . ($i + 1);
Expand All @@ -82,7 +84,14 @@ public function run(): void
)
);
file_put_contents($filename, implode("\n", $tests));
$filenames[] = $filename;
}

$numFiles = count($filenames);

return Result::success($this, "Split all tests into $numFiles group files", [
'files' => $filenames,
]);
}

/**
Expand Down
13 changes: 11 additions & 2 deletions src/Splitter/TestFileSplitterTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Codeception\Task\Splitter;

use Robo\Result;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Finder\SplFileInfo;

Expand All @@ -29,7 +30,7 @@ class TestFileSplitterTask extends TestsSplitter
{
private $pattern = ['*Cept.php', '*Cest.php', '*Test.php', '*.feature'];

public function run()
public function run(): Result
{
$files = Finder::create()
->followLinks()
Expand All @@ -38,14 +39,22 @@ public function run()
->in($this->projectRoot ?: getcwd())
->exclude($this->excludePath);

$this->splitToGroupFiles(


$filenames = $this->splitToGroupFiles(
array_map(
static function (SplFileInfo $fileInfo): string {
return $fileInfo->getRelativePathname();
},
$this->filter(iterator_to_array($files->getIterator()))
)
);

$numFiles = count($filenames);

return Result::success($this, "Split all tests into $numFiles group files", [
'files' => $filenames,
]);
}

/**
Expand Down
14 changes: 13 additions & 1 deletion src/Splitter/TestsSplitter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Codeception\Task\Splitter;

use Codeception\Configuration;
use Codeception\Task\Filter\DefaultFilter;
use Codeception\Task\Filter\Filter;
use ReflectionClass;
Expand Down Expand Up @@ -208,6 +209,8 @@ protected function claimCodeceptionLoaded(): void
'This task requires Codeception to be loaded. Please require autoload.php of Codeception'
);
}
// autoload PHPUnit files
\Codeception\PHPUnit\Init::init();
}

/**
Expand All @@ -223,11 +226,17 @@ protected function doCodeceptLoaderExists(): bool
* @param string[] $files - the relative path of the Testfile with or without test function
* @example $this->splitToGroupFiles(['tests/FooCest.php', 'tests/BarTest.php:testBarReturn']);
*/
protected function splitToGroupFiles(array $files): void
protected function splitToGroupFiles(array $files): array
{
$i = 0;
$groups = [];

if (!Configuration::projectDir()) {
$this->output()->writeln("Codeception config was not loaded, paths to tests may not be set correctly.");
$this->output()->writeln("Execute \Codeception\Configuration::config() before this task");
}


$this->printTaskInfo('Processing ' . count($files) . ' files');

// splitting tests by groups
Expand All @@ -237,11 +246,14 @@ protected function splitToGroupFiles(array $files): void
$i++;
}

$filenames = [];
// saving group files
foreach ($groups as $i => $tests) {
$filename = $this->saveTo . $i;
$this->printTaskInfo("Writing $filename");
file_put_contents($filename, implode("\n", $tests));
$filenames[] = $filename;
}
return $filenames;
}
}
24 changes: 16 additions & 8 deletions src/Splitter/TestsSplitterTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PHPUnit\Framework\DataProviderTestSuite;
use PHPUnit\Framework\TestCase;
use ReflectionObject;
use Robo\Result;

/**
* Loads all tests into groups and saves them to groupfile according to pattern.
Expand All @@ -32,14 +33,14 @@ class TestsSplitterTask extends TestsSplitter
{

/**
* @return bool|null
* @throws \Robo\Exception\TaskException
*/
public function run()
public function run(): Result
{
$this->claimCodeceptionLoaded();
$tests = $this->filter($this->loadTests());
$this->printTaskInfo('Processing ' . count($tests) . ' tests');
$numTests = count($tests);
$this->printTaskInfo("Processing $numTests tests");

$testsHaveAtLeastOneDependency = false;

Expand Down Expand Up @@ -98,7 +99,7 @@ public function run()
);
} catch (Exception $e) {
$this->printTaskError($e->getMessage());
return false;
return Result::error($this, $e->getMessage(), ['exception' => $e]);
}
// resolved and ordered list of dependencies
$orderedListOfTests = [];
Expand All @@ -116,7 +117,7 @@ public function run()
);
} catch (Exception $e) {
$this->printTaskError($e->getMessage());
return false;
return Result::error($this, $e->getMessage(), ['exception' => $e]);
}
}
// if we don't have any dependencies just use keys from original list.
Expand Down Expand Up @@ -145,14 +146,21 @@ public function run()
$groups[$i][] = $test;
}

$filenames = [];
// saving group files
foreach ($groups as $i => $tests) {
foreach ($groups as $i => $groupTests) {
$filename = $this->saveTo . $i;
$this->printTaskInfo("Writing $filename");
file_put_contents($filename, implode("\n", $tests));
file_put_contents($filename, implode("\n", $groupTests));
$filenames[] = $filename;
}
$numFiles = count($filenames);

return null;
return Result::success($this, "Split $numTests into $numFiles group files", [
'groups' => $groups,
'tests' => $tests,
'files' => $filenames,
]);
}

/**
Expand Down
9 changes: 8 additions & 1 deletion tests/Splitter/TestsSplitterTaskTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,14 @@ public function testLoadTests(
$task->testsFrom($from);
$groupTo = TEST_PATH . '/result/group_';
$task->groupsTo($groupTo);
$task->run();
$result = $task->run();

$this->assertNotEmpty($result);

if ($expectedFiles > 0) {
$this->assertTrue($result->wasSuccessful());
$this->assertEquals($expectedFiles, count($result['files']));
}

$files = Finder::create()
->files()
Expand Down

0 comments on commit 616747b

Please sign in to comment.