Skip to content

Commit f516f1e

Browse files
authored
Merge pull request #126 from magento-commerce/MQE-2677
MQE-2677: Add filter for groups
2 parents 537fe57 + b500d4d commit f516f1e

File tree

5 files changed

+250
-3
lines changed

5 files changed

+250
-3
lines changed

dev/tests/unit/Magento/FunctionalTestFramework/Util/TestGeneratorTest.php

Lines changed: 131 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public function testAllowSkipped(): void
162162
* @return void
163163
* @throws TestReferenceException
164164
*/
165-
public function testFilter(): void
165+
public function testSeverityFilter(): void
166166
{
167167
$mockConfig = $this->createMock(MftfApplicationConfig::class);
168168
$fileList = new FilterList(['severity' => ['CRITICAL']]);
@@ -221,6 +221,136 @@ function ($filename) use (&$generatedTests) {
221221
$this->assertArrayNotHasKey('test2Cest', $generatedTests);
222222
}
223223

224+
/**
225+
* Tests that TestGenerator createAllTestFiles correctly filters based on group.
226+
*
227+
* @return void
228+
* @throws TestReferenceException
229+
*/
230+
public function testIncludeGroupFilter(): void
231+
{
232+
$mockConfig = $this->createMock(MftfApplicationConfig::class);
233+
$fileList = new FilterList(['includeGroup' => ['someGroupValue']]);
234+
$mockConfig
235+
->method('getFilterList')
236+
->willReturn($fileList);
237+
238+
$property = new ReflectionProperty(MftfApplicationConfig::class, 'MFTF_APPLICATION_CONTEXT');
239+
$property->setAccessible(true);
240+
$property->setValue($mockConfig);
241+
242+
$actionInput = 'fakeInput';
243+
$actionObject = new ActionObject('fakeAction', 'comment', [
244+
'userInput' => $actionInput
245+
]);
246+
247+
$annotation1 = ['group' => ['someGroupValue']];
248+
$annotation2 = ['group' => ['someOtherGroupValue']];
249+
$test1 = new TestObject(
250+
'test1',
251+
['fakeAction' => $actionObject],
252+
$annotation1,
253+
[],
254+
'filename'
255+
);
256+
$test2 = new TestObject(
257+
'test2',
258+
['fakeAction' => $actionObject],
259+
$annotation2,
260+
[],
261+
'filename'
262+
);
263+
264+
// Mock createCestFile to return name of tests that testGenerator tried to create
265+
$generatedTests = [];
266+
$cestFileCreatorUtil = $this->createMock(CestFileCreatorUtil::class);
267+
$cestFileCreatorUtil
268+
->method('create')
269+
->will(
270+
$this->returnCallback(
271+
function ($filename) use (&$generatedTests) {
272+
$generatedTests[$filename] = true;
273+
}
274+
)
275+
);
276+
277+
$property = new ReflectionProperty(CestFileCreatorUtil::class, 'INSTANCE');
278+
$property->setAccessible(true);
279+
$property->setValue($cestFileCreatorUtil);
280+
281+
$testGeneratorObject = TestGenerator::getInstance('', ['sampleTest' => $test1, 'test2' => $test2]);
282+
$testGeneratorObject->createAllTestFiles();
283+
284+
// Ensure Test1 was Generated but not Test 2
285+
$this->assertArrayHasKey('test1Cest', $generatedTests);
286+
$this->assertArrayNotHasKey('test2Cest', $generatedTests);
287+
}
288+
289+
/**
290+
* Tests that TestGenerator createAllTestFiles correctly filters based on group not included.
291+
*
292+
* @return void
293+
* @throws TestReferenceException
294+
*/
295+
public function testExcludeGroupFilter(): void
296+
{
297+
$mockConfig = $this->createMock(MftfApplicationConfig::class);
298+
$fileList = new FilterList(['excludeGroup' => ['someGroupValue']]);
299+
$mockConfig
300+
->method('getFilterList')
301+
->willReturn($fileList);
302+
303+
$property = new ReflectionProperty(MftfApplicationConfig::class, 'MFTF_APPLICATION_CONTEXT');
304+
$property->setAccessible(true);
305+
$property->setValue($mockConfig);
306+
307+
$actionInput = 'fakeInput';
308+
$actionObject = new ActionObject('fakeAction', 'comment', [
309+
'userInput' => $actionInput
310+
]);
311+
312+
$annotation1 = ['group' => ['someGroupValue']];
313+
$annotation2 = ['group' => ['someOtherGroupValue']];
314+
$test1 = new TestObject(
315+
'test1',
316+
['fakeAction' => $actionObject],
317+
$annotation1,
318+
[],
319+
'filename'
320+
);
321+
$test2 = new TestObject(
322+
'test2',
323+
['fakeAction' => $actionObject],
324+
$annotation2,
325+
[],
326+
'filename'
327+
);
328+
329+
// Mock createCestFile to return name of tests that testGenerator tried to create
330+
$generatedTests = [];
331+
$cestFileCreatorUtil = $this->createMock(CestFileCreatorUtil::class);
332+
$cestFileCreatorUtil
333+
->method('create')
334+
->will(
335+
$this->returnCallback(
336+
function ($filename) use (&$generatedTests) {
337+
$generatedTests[$filename] = true;
338+
}
339+
)
340+
);
341+
342+
$property = new ReflectionProperty(CestFileCreatorUtil::class, 'INSTANCE');
343+
$property->setAccessible(true);
344+
$property->setValue($cestFileCreatorUtil);
345+
346+
$testGeneratorObject = TestGenerator::getInstance('', ['sampleTest' => $test1, 'test2' => $test2]);
347+
$testGeneratorObject->createAllTestFiles();
348+
349+
// Ensure Test2 was Generated but not Test 1
350+
$this->assertArrayNotHasKey('test1Cest', $generatedTests);
351+
$this->assertArrayHasKey('test2Cest', $generatedTests);
352+
}
353+
224354
/**
225355
* @inheritDoc
226356
*/

docs/commands/mftf.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ vendor/bin/mftf generate:tests [option] [<test name>] [<test name>] [--remove]
160160
| Option | Description|
161161
| ---| --- |
162162
| `--config=[<default> or <singleRun> or <parallel>]` | Creates a single manifest file with a list of all tests. The default location is `tests/functional/Magento/FunctionalTest/_generated/testManifest.txt`.<br/> You can split the list into multiple groups using `--config=parallel`; the groups will be generated in `_generated/groups/` like `_generated/groups/group1.txt, group2.txt, ...`.<br/> Available values: `default` (default), `singleRun`(same as `default`), and `parallel`.<br/> Example: `generate:tests --config=parallel`. |
163-
| `--filter` | Option to filter tests to be generated.<br/>Template: '&lt;filterName&gt;:&lt;filterValue&gt;'.<br/>Existing filter types: severity.<br/>Existing severity values: BLOCKER, CRITICAL, MAJOR, AVERAGE, MINOR.<br/>Example: `--filter=severity:CRITICAL`|
163+
| `--filter` | Option to filter tests to be generated.<br/>Template: '&lt;filterName&gt;:&lt;filterValue&gt;'.<br/>Existing filter types: severity, includeGroup, excludeGroup.<br/>Existing severity values: BLOCKER, CRITICAL, MAJOR, AVERAGE, MINOR.<br/>Example: `vendor/bin/mftf generate:tests --filter=severity:CRITICAL --filter=severity:BLOCKER --filter=includeGroup:customer`|
164164
| `--force` | Forces test generation, regardless of the module merge order defined in the Magento instance. Example: `generate:tests --force`. |
165165
| `-i,--time` | Set time in minutes to determine the group size when `--config=parallel` is used. <br/>Example: `generate:tests --config=parallel --time=15` <br/>Option `--time` will be the default and the __default value__ is `10` when neither `--time` nor `--groups` is specified. <br/>Example: `generate:tests --config=parallel`|
166166
| `-g,--groups` | Set number of groups to be split into when `--config=parallel` is used. <br>Example: `generate:tests --config=parallel --groups=300` <br/>Options `--time` and `--groups` are mutually exclusive and only one should be used.|

src/Magento/FunctionalTestingFramework/Console/GenerateTestsCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ protected function configure()
7878
. '<info>Template:</info> <filterName>:<filterValue>' . PHP_EOL
7979
. '<info>Existing filter types:</info> severity.' . PHP_EOL
8080
. '<info>Existing severity values:</info> BLOCKER, CRITICAL, MAJOR, AVERAGE, MINOR.' . PHP_EOL
81-
. '<info>Example:</info> --filter=severity:CRITICAL' . PHP_EOL
81+
. '<info>Example:</info> --filter=severity:CRITICAL'
82+
. ' --filter=includeGroup:customer --filter=excludeGroup:customerAnalytics' . PHP_EOL
8283
);
8384

8485
parent::configure();
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\FunctionalTestingFramework\Filter\Test;
10+
11+
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
12+
use Magento\FunctionalTestingFramework\Filter\FilterInterface;
13+
use Magento\FunctionalTestingFramework\Test\Objects\TestObject;
14+
15+
/**
16+
* Class ExcludeGroup
17+
*/
18+
class ExcludeGroup implements FilterInterface
19+
{
20+
const ANNOTATION_TAG = 'group';
21+
22+
/**
23+
* @var array
24+
*/
25+
private $filterValues = [];
26+
27+
/**
28+
* Group constructor.
29+
*
30+
* @param array $filterValues
31+
* @throws TestFrameworkException
32+
*/
33+
public function __construct(array $filterValues = [])
34+
{
35+
$this->filterValues = $filterValues;
36+
}
37+
38+
/**
39+
* Filter tests by group.
40+
*
41+
* @param TestObject[] $tests
42+
* @return void
43+
*/
44+
public function filter(array &$tests)
45+
{
46+
if ($this->filterValues === []) {
47+
return;
48+
}
49+
/** @var TestObject $test */
50+
foreach ($tests as $testName => $test) {
51+
$groups = $test->getAnnotationByName(self::ANNOTATION_TAG);
52+
$testExcludeGroup = !empty(array_intersect($groups, $this->filterValues));
53+
if ($testExcludeGroup) {
54+
unset($tests[$testName]);
55+
}
56+
}
57+
}
58+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\FunctionalTestingFramework\Filter\Test;
10+
11+
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
12+
use Magento\FunctionalTestingFramework\Filter\FilterInterface;
13+
use Magento\FunctionalTestingFramework\Test\Objects\TestObject;
14+
15+
/**
16+
* Class IncludeGroup
17+
*/
18+
class IncludeGroup implements FilterInterface
19+
{
20+
const ANNOTATION_TAG = 'group';
21+
22+
/**
23+
* @var array
24+
*/
25+
private $filterValues = [];
26+
27+
/**
28+
* Group constructor.
29+
*
30+
* @param array $filterValues
31+
* @throws TestFrameworkException
32+
*/
33+
public function __construct(array $filterValues = [])
34+
{
35+
$this->filterValues = $filterValues;
36+
}
37+
38+
/**
39+
* Filter tests by group.
40+
*
41+
* @param TestObject[] $tests
42+
* @return void
43+
*/
44+
public function filter(array &$tests)
45+
{
46+
if ($this->filterValues === []) {
47+
return;
48+
}
49+
/** @var TestObject $test */
50+
foreach ($tests as $testName => $test) {
51+
$groups = $test->getAnnotationByName(self::ANNOTATION_TAG);
52+
$testIncludeGroup = empty(array_intersect($groups, $this->filterValues));
53+
if ($testIncludeGroup) {
54+
unset($tests[$testName]);
55+
}
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)