Skip to content

Commit 35dd1fe

Browse files
committed
MQE-982: Verification Test around Suite Generation
- Adding Tests for Parallel Suite Generation and Suite Hook Verification
1 parent fb1e4b7 commit 35dd1fe

File tree

3 files changed

+255
-9
lines changed

3 files changed

+255
-9
lines changed

dev/_suite/functionalSuiteHooks.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<suites xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../src/Magento/FunctionalTestingFramework/Suite/etc/suiteSchema.xsd">
10+
<suite name="functionalSuiteHooks">
11+
<include>
12+
<test name="IncludeTest"/>
13+
</include>
14+
<before>
15+
<amOnPage url="some.url" stepKey="before"/>
16+
</before>
17+
<after>
18+
<amOnPage url="some.url" stepKey="after"/>
19+
</after>
20+
</suite>
21+
</suites>
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
namespace Group;
4+
5+
use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler;
6+
use Magento\FunctionalTestingFramework\DataGenerator\Persist\DataPersistenceHandler;
7+
8+
/**
9+
* Group class is Codeception Extension which is allowed to handle to all internal events.
10+
* This class itself can be used to listen events for test execution of one particular group.
11+
* It may be especially useful to create fixtures data, prepare server, etc.
12+
*
13+
* INSTALLATION:
14+
*
15+
* To use this group extension, include it to "extensions" option of global Codeception config.
16+
*/
17+
class functionalSuiteHooks extends \Codeception\GroupObject
18+
{
19+
public static $group = 'functionalSuiteHooks';
20+
private $testCount = 1;
21+
private $preconditionFailure = null;
22+
private $currentTestRun = 0;
23+
private static $HOOK_EXECUTION_INIT = "\n/******** Beginning execution of functionalSuiteHooks suite %s block ********/\n";
24+
private static $HOOK_EXECUTION_END = "\n/******** Execution of functionalSuiteHooks suite %s block complete ********/\n";
25+
26+
public function _before(\Codeception\Event\TestEvent $e)
27+
{
28+
// increment test count per execution
29+
$this->currentTestRun++;
30+
$this->executePreConditions();
31+
32+
if ($this->preconditionFailure != null) {
33+
//if our preconditions fail, we need to mark all the tests as incomplete.
34+
$e->getTest()->getMetadata()->setIncomplete($this->preconditionFailure);
35+
}
36+
}
37+
38+
39+
private function executePreConditions()
40+
{
41+
if ($this->currentTestRun == 1) {
42+
print sprintf(self::$HOOK_EXECUTION_INIT, "before");
43+
44+
try {
45+
$webDriver = $this->getModule('\Magento\FunctionalTestingFramework\Module\MagentoWebDriver');
46+
47+
// close any open sessions
48+
if ($webDriver->webDriver != null) {
49+
$webDriver->webDriver->close();
50+
$webDriver->webDriver = null;
51+
}
52+
53+
// initialize the webdriver session
54+
$webDriver->_initializeSession();
55+
$webDriver->amOnPage("some.url");
56+
57+
// reset configuration and close session
58+
$this->getModule('\Magento\FunctionalTestingFramework\Module\MagentoWebDriver')->_resetConfig();
59+
$webDriver->webDriver->close();
60+
$webDriver->webDriver = null;
61+
} catch (\Exception $exception) {
62+
$this->preconditionFailure = $exception->getMessage();
63+
}
64+
65+
print sprintf(self::$HOOK_EXECUTION_END, "before");
66+
}
67+
}
68+
69+
public function _after(\Codeception\Event\TestEvent $e)
70+
{
71+
$this->executePostConditions();
72+
}
73+
74+
75+
private function executePostConditions()
76+
{
77+
if ($this->currentTestRun == $this->testCount) {
78+
print sprintf(self::$HOOK_EXECUTION_INIT, "after");
79+
80+
try {
81+
$webDriver = $this->getModule('\Magento\FunctionalTestingFramework\Module\MagentoWebDriver');
82+
83+
// close any open sessions
84+
if ($webDriver->webDriver != null) {
85+
$webDriver->webDriver->close();
86+
$webDriver->webDriver = null;
87+
}
88+
89+
// initialize the webdriver session
90+
$webDriver->_initializeSession();
91+
$webDriver->amOnPage("some.url");
92+
93+
// reset configuration and close session
94+
$this->getModule('\Magento\FunctionalTestingFramework\Module\MagentoWebDriver')->_resetConfig();
95+
$webDriver->webDriver->close();
96+
$webDriver->webDriver = null;
97+
} catch (\Exception $exception) {
98+
print $exception->getMessage();
99+
}
100+
101+
print sprintf(self::$HOOK_EXECUTION_END, "after");
102+
}
103+
}
104+
}

dev/tests/verification/Tests/SuiteGenerationTest.php

Lines changed: 130 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,22 @@
88

99
use Magento\Framework\Module\Dir;
1010
use Magento\FunctionalTestingFramework\Suite\SuiteGenerator;
11-
use Magento\FunctionalTestingFramework\Util\TestManifest;
11+
use Magento\FunctionalTestingFramework\Util\Filesystem\DirSetupUtil;
12+
use Magento\FunctionalTestingFramework\Util\Manifest\ParallelTestManifest;
13+
use Magento\FunctionalTestingFramework\Util\Manifest\TestManifestFactory;
1214
use Symfony\Component\Yaml\Yaml;
1315
use tests\util\MftfTestCase;
1416

1517
class SuiteGenerationTest extends MftfTestCase
1618
{
1719
const RESOURCES_DIR = TESTS_BP . DIRECTORY_SEPARATOR . 'verification' . DIRECTORY_SEPARATOR . 'Resources';
1820
const CONFIG_YML_FILE = FW_BP . DIRECTORY_SEPARATOR . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME;
21+
const GENERATE_RESULT_DIR = TESTS_BP .
22+
DIRECTORY_SEPARATOR .
23+
"verification" .
24+
DIRECTORY_SEPARATOR .
25+
"_generated" .
26+
DIRECTORY_SEPARATOR;
1927

2028
/**
2129
* Flag to track existence of config.yml file
@@ -75,11 +83,94 @@ public function testSuiteGeneration1()
7583
$yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
7684
$this->assertArrayHasKey($groupName, $yml['groups']);
7785

78-
$suiteResultBaseDir = TESTS_BP .
86+
$suiteResultBaseDir = self::GENERATE_RESULT_DIR .
7987
DIRECTORY_SEPARATOR .
80-
"verification" .
81-
DIRECTORY_SEPARATOR .
82-
"_generated" .
88+
$groupName .
89+
DIRECTORY_SEPARATOR;
90+
91+
// Validate tests have been generated
92+
$dirContents = array_diff(scandir($suiteResultBaseDir), ['..', '.']);
93+
94+
foreach ($expectedContents as $expectedFile) {
95+
$this->assertTrue(in_array($expectedFile, $dirContents));
96+
}
97+
}
98+
99+
/**
100+
* Test generation of parallel suite groups
101+
*/
102+
public function testSuiteGenerationParallel()
103+
{
104+
$groupName = 'functionalSuite1';
105+
106+
$expectedGroups = [
107+
'functionalSuite1_0',
108+
'functionalSuite1_1',
109+
'functionalSuite1_2',
110+
'functionalSuite1_3'
111+
];
112+
113+
$expectedContents = [
114+
'additionalTestCest.php',
115+
'additionalIncludeTest2Cest.php',
116+
'IncludeTest2Cest.php',
117+
'IncludeTestCest.php'
118+
];
119+
120+
//createParallelManifest
121+
/** @var ParallelTestManifest $parallelManifest */
122+
$parallelManifest = TestManifestFactory::makeManifest("parallel", ["functionalSuite1" => []]);
123+
124+
// Generate the Suite
125+
$parallelManifest->createTestGroups(1);
126+
SuiteGenerator::getInstance()->generateAllSuites($parallelManifest);
127+
128+
// Validate console message and add group name for later deletion
129+
$this->expectOutputRegex('/Suite .* generated to .*/');
130+
self::$TEST_GROUPS[] = $groupName;
131+
132+
// Validate Yaml file updated
133+
$yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
134+
$this->assertEquals($expectedGroups, array_keys($yml['groups']));
135+
136+
foreach ($expectedGroups as $expectedFolder) {
137+
$suiteResultBaseDir = self::GENERATE_RESULT_DIR .
138+
DIRECTORY_SEPARATOR .
139+
$expectedFolder .
140+
DIRECTORY_SEPARATOR;
141+
142+
// Validate tests have been generated
143+
$dirContents = array_diff(scandir($suiteResultBaseDir), ['..', '.']);
144+
145+
//Validate only one test has been added to each group since lines are set to 1
146+
$this->assertEquals(1, count($dirContents));
147+
$this->assertContains(array_values($dirContents)[0], $expectedContents);
148+
}
149+
}
150+
151+
/**
152+
* Test hook groups generated during suite generation
153+
*/
154+
public function testSuiteGenerationHooks()
155+
{
156+
$groupName = 'functionalSuiteHooks';
157+
158+
$expectedContents = [
159+
'IncludeTestCest.php'
160+
];
161+
162+
// Generate the Suite
163+
SuiteGenerator::getInstance()->generateSuite($groupName);
164+
165+
// Validate console message and add group name for later deletion
166+
$this->expectOutputRegex('/Suite .* generated to .*/');
167+
self::$TEST_GROUPS[] = $groupName;
168+
169+
// Validate Yaml file updated
170+
$yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
171+
$this->assertArrayHasKey($groupName, $yml['groups']);
172+
173+
$suiteResultBaseDir = self::GENERATE_RESULT_DIR .
83174
DIRECTORY_SEPARATOR .
84175
$groupName .
85176
DIRECTORY_SEPARATOR;
@@ -90,25 +181,55 @@ public function testSuiteGeneration1()
90181
foreach ($expectedContents as $expectedFile) {
91182
$this->assertTrue(in_array($expectedFile, $dirContents));
92183
}
184+
185+
//assert group file created and contains correct contents
186+
$groupFile = PROJECT_ROOT .
187+
DIRECTORY_SEPARATOR .
188+
"src" .
189+
DIRECTORY_SEPARATOR .
190+
"Magento" .
191+
DIRECTORY_SEPARATOR .
192+
"FunctionalTestingFramework" .
193+
DIRECTORY_SEPARATOR .
194+
"Group" .
195+
DIRECTORY_SEPARATOR .
196+
$groupName .
197+
".php";
198+
199+
$this->assertTrue(file_exists($groupFile));
200+
$this->assertFileEquals(
201+
self::RESOURCES_PATH . DIRECTORY_SEPARATOR . $groupName . ".txt",
202+
$groupFile
203+
);
204+
93205
}
94206

95207
/**
96208
* revert any changes made to config.yml
209+
* remove _generated directory
97210
*/
98-
public static function tearDownAfterClass()
211+
public function tearDown()
99212
{
100213
// restore config if we see there was an original codeception.yml file
101214
if (self::$YML_EXISTS_FLAG) {
102215
$yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
103216
foreach (self::$TEST_GROUPS as $testGroup) {
104-
unset($yml['group'][$testGroup]);
217+
unset($yml['groups'][$testGroup]);
105218
}
106219

107220
file_put_contents(self::CONFIG_YML_FILE, Yaml::dump($yml, 10));
108-
return;
109221
}
222+
DirSetupUtil::rmdirRecursive(self::GENERATE_RESULT_DIR);
223+
}
110224

111-
unlink(self::CONFIG_YML_FILE);
225+
/**
226+
* Remove yml if created during tests and did not exist before
227+
*/
228+
public static function tearDownAfterClass()
229+
{
230+
if (!self::$YML_EXISTS_FLAG) {
231+
unlink(self::CONFIG_YML_FILE);
232+
}
112233
}
113234

114235
/**

0 commit comments

Comments
 (0)