Skip to content

Commit b35c503

Browse files
authoredMar 29, 2018
Merge pull request #74 from magento/MQE-778
MQE-778: robo generate:tests generates all tests and suites by default
2 parents 6ab66f3 + 07eae39 commit b35c503

File tree

7 files changed

+165
-36
lines changed

7 files changed

+165
-36
lines changed
 

‎dev/tests/verification/Tests/SuiteGenerationTest.php

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,6 @@ class SuiteGenerationTest extends MftfTestCase
1717
const RESOURCES_DIR = TESTS_BP . DIRECTORY_SEPARATOR . 'verification' . DIRECTORY_SEPARATOR . 'Resources';
1818
const CONFIG_YML_FILE = FW_BP . DIRECTORY_SEPARATOR . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME;
1919

20-
const MANIFEST_RESULTS = [
21-
'IncludeTest2Cest.php',
22-
'additionalTestCest.php',
23-
'IncludeTestCest.php',
24-
'additionalIncludeTest2Cest.php'
25-
];
26-
2720
/**
2821
* Flag to track existence of config.yml file
2922
*
@@ -48,6 +41,11 @@ public static function setUpBeforeClass()
4841
return;
4942
}
5043

44+
// destroy manifest file if it exists
45+
if (file_exists(self::getManifestFilePath())) {
46+
unlink(self::getManifestFilePath());
47+
}
48+
5149
$configYml = fopen(self::CONFIG_YML_FILE, "w");
5250
fclose($configYml);
5351
}
@@ -59,6 +57,13 @@ public function testSuiteGeneration1()
5957
{
6058
$groupName = 'functionalSuite1';
6159

60+
$expectedContents = [
61+
'additionalTestCest.php',
62+
'additionalIncludeTest2Cest.php',
63+
'IncludeTest2Cest.php',
64+
'IncludeTestCest.php'
65+
];
66+
6267
// Generate the Suite
6368
SuiteGenerator::getInstance()->generateSuite($groupName);
6469

@@ -79,23 +84,10 @@ public function testSuiteGeneration1()
7984
$groupName .
8085
DIRECTORY_SEPARATOR;
8186

82-
// Validate test manifest contents
83-
$actualManifest = dirname($suiteResultBaseDir). DIRECTORY_SEPARATOR . 'testManifest.txt';
84-
$actualTestReferences = explode(PHP_EOL, file_get_contents($actualManifest));
85-
86-
for ($i = 0; $i < count($actualTestReferences); $i++) {
87-
if (empty($actualTestReferences[$i])) {
88-
continue;
89-
}
90-
91-
$this->assertStringEndsWith(self::MANIFEST_RESULTS[$i], $actualTestReferences[$i]);
92-
$this->assertNotFalse(strpos($actualTestReferences[$i], $groupName));
93-
}
94-
95-
// Validate expected php files exist
96-
foreach (self::MANIFEST_RESULTS as $expectedTestReference) {
97-
$cestName = explode(":", $expectedTestReference, 2);
98-
$this->assertFileExists($suiteResultBaseDir . $cestName[0]);
87+
// Validate tests have been generated
88+
$dirContents = array_diff(scandir($suiteResultBaseDir), ['..', '.']);
89+
foreach ($expectedContents as $expectedFile) {
90+
$this->assertTrue(in_array($expectedFile, $dirContents));
9991
}
10092
}
10193

@@ -117,4 +109,20 @@ public static function tearDownAfterClass()
117109

118110
unlink(self::CONFIG_YML_FILE);
119111
}
112+
113+
/**
114+
* Getter for manifest file path
115+
*
116+
* @return string
117+
*/
118+
private static function getManifestFilePath()
119+
{
120+
return TESTS_BP .
121+
DIRECTORY_SEPARATOR .
122+
"verification" .
123+
DIRECTORY_SEPARATOR .
124+
"_generated" .
125+
DIRECTORY_SEPARATOR .
126+
'testManifest.txt';
127+
}
120128
}

‎src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ class SuiteGenerator
3232
*/
3333
private static $SUITE_GENERATOR_INSTANCE;
3434

35+
/**
36+
* Boolean to track whether we have already cleared the yaml file.
37+
*
38+
* @var bool
39+
*/
40+
private $ymlFileCleared = false;
41+
3542
/**
3643
* Group Class Generator initialized in constructor.
3744
*
@@ -61,14 +68,35 @@ public static function getInstance()
6168
return self::$SUITE_GENERATOR_INSTANCE;
6269
}
6370

71+
/**
72+
* Function which takes all suite configurations and generates to appropriate directory, updating yml configuration
73+
* as needed. Returns an array of all tests generated keyed by test name.
74+
*
75+
* @param string $config
76+
* @return array
77+
*/
78+
public function generateAllSuites($config)
79+
{
80+
$testsReferencedInSuites = [];
81+
$suites = SuiteObjectHandler::getInstance()->getAllObjects();
82+
foreach ($suites as $suite) {
83+
/** @var SuiteObject $suite */
84+
$testsReferencedInSuites = array_merge($testsReferencedInSuites, $suite->getTests());
85+
$this->generateSuite($suite->getName(), $config);
86+
}
87+
88+
return $testsReferencedInSuites;
89+
}
90+
6491
/**
6592
* Function which takes a suite name and generates corresponding dir, test files, group class, and updates
6693
* yml configuration for group run.
6794
*
6895
* @param string $suiteName
96+
* @param string $config
6997
* @return void
7098
*/
71-
public function generateSuite($suiteName)
99+
public function generateSuite($suiteName, $config = null)
72100
{
73101
/**@var SuiteObject $suite **/
74102
$suite = SuiteObjectHandler::getInstance()->getObject($suiteName);
@@ -77,7 +105,7 @@ public function generateSuite($suiteName)
77105
$groupNamespace = null;
78106

79107
DirSetupUtil::createGroupDir($fullPath);
80-
$this->generateRelevantGroupTests($suiteName, $suite->getTests());
108+
$this->generateRelevantGroupTests($suiteName, $suite->getTests(), $config);
81109

82110
if ($suite->requiresGroupFile()) {
83111
// if the suite requires a group file, generate it and set the namespace
@@ -117,29 +145,69 @@ private function appendEntriesToConfig($suiteName, $suitePath, $groupNamespace)
117145
$ymlArray[self::YAML_GROUPS_TAG]= [];
118146
}
119147

120-
$ymlArray[self::YAML_GROUPS_TAG][$suiteName] = [$relativeSuitePath];
148+
$ymlArray = $this->clearPreviousSessionConfigEntries($ymlArray);
121149

122-
if ($groupNamespace &&
123-
!in_array($groupNamespace, $ymlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG])) {
150+
if ($groupNamespace) {
124151
$ymlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG][] = $groupNamespace;
125152
}
153+
$ymlArray[self::YAML_GROUPS_TAG][$suiteName] = [$relativeSuitePath];
126154

127155
$ymlText = self::YAML_COPYRIGHT_TEXT . Yaml::dump($ymlArray, 10);
128156
file_put_contents($configYmlFile, $ymlText);
129157
}
130158

159+
/**
160+
* Function which takes the current config.yml array and clears any previous configuration for suite group object
161+
* files.
162+
*
163+
* @param array $ymlArray
164+
* @return array
165+
*/
166+
private function clearPreviousSessionConfigEntries($ymlArray)
167+
{
168+
if ($this->ymlFileCleared) {
169+
return $ymlArray;
170+
}
171+
172+
$newYmlArray = $ymlArray;
173+
// if the yaml entries haven't already been cleared
174+
175+
if (array_key_exists(self::YAML_EXTENSIONS_TAG, $ymlArray)) {
176+
foreach ($ymlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG] as $key => $entry) {
177+
if (preg_match('/(Group\\\\.*)/', $entry)) {
178+
unset($newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG][$key]);
179+
}
180+
181+
}
182+
183+
// needed for proper yml file generation based on indices
184+
$newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG] =
185+
array_values($newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG]);
186+
187+
}
188+
189+
if (array_key_exists(self::YAML_GROUPS_TAG, $newYmlArray)) {
190+
unset($newYmlArray[self::YAML_GROUPS_TAG]);
191+
}
192+
193+
$this->ymlFileCleared = true;
194+
195+
return $newYmlArray;
196+
}
197+
131198
/**
132199
* Function which takes a string which is the desired output directory (under _generated) and an array of tests
133200
* relevant to the suite to be generated. The function takes this information and creates a new instance of the test
134201
* generator which is then called to create all the test files for the suite.
135202
*
136203
* @param string $path
137204
* @param array $tests
205+
* @param string $config
138206
* @return void
139207
*/
140-
private function generateRelevantGroupTests($path, $tests)
208+
private function generateRelevantGroupTests($path, $tests, $config)
141209
{
142210
$testGenerator = TestGenerator::getInstance($path, $tests);
143-
$testGenerator->createAllTestFiles();
211+
$testGenerator->createAllTestFiles($config);
144212
}
145213
}

‎src/Magento/FunctionalTestingFramework/Suite/Util/SuiteObjectExtractor.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ public function parseSuiteDataIntoObjects($parsedSuiteData)
4444
{
4545
$suiteObjects = [];
4646
$testHookObjectExtractor = new TestHookObjectExtractor();
47+
48+
// make sure there are suites defined before trying to parse as objects.
49+
if (!array_key_exists(self::SUITE_ROOT_TAG, $parsedSuiteData)) {
50+
return $suiteObjects;
51+
}
52+
4753
foreach ($parsedSuiteData[self::SUITE_ROOT_TAG] as $parsedSuite) {
4854
if (!is_array($parsedSuite)) {
4955
// skip non array items parsed from suite (suite objects will always be arrays)

‎src/Magento/FunctionalTestingFramework/Util/Filesystem/DirSetupUtil.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111

1212
class DirSetupUtil
1313
{
14+
/**
15+
* Array which will track any previously cleared directories, to prevent any unintended removal.
16+
*
17+
* @var array
18+
*/
19+
private static $DIR_CONTEXT = [];
20+
1421
/**
1522
* Method used to clean export dir if needed and create new empty export dir.
1623
*
@@ -19,11 +26,17 @@ class DirSetupUtil
1926
*/
2027
public static function createGroupDir($fullPath)
2128
{
29+
// make sure we haven't already cleaned up this directory at any point before deletion
30+
if (in_array($fullPath, self::$DIR_CONTEXT)) {
31+
return;
32+
}
33+
2234
if (file_exists($fullPath)) {
2335
self::rmDirRecursive($fullPath);
2436
}
2537

2638
mkdir($fullPath, 0777, true);
39+
self::$DIR_CONTEXT[] = $fullPath;
2740
}
2841

2942
/**

‎src/Magento/FunctionalTestingFramework/Util/Manifest/DefaultTestManifest.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace Magento\FunctionalTestingFramework\Util\Manifest;
88

99
use Magento\FunctionalTestingFramework\Test\Objects\TestObject;
10+
use Magento\FunctionalTestingFramework\Util\Filesystem\DirSetupUtil;
1011

1112
class DefaultTestManifest extends BaseTestManifest
1213
{
@@ -19,6 +20,13 @@ class DefaultTestManifest extends BaseTestManifest
1920
*/
2021
protected $manifestPath;
2122

23+
/**
24+
* A static array to track which test manifests have been cleared to prevent overwriting during generation.
25+
*
26+
* @var array
27+
*/
28+
private static $CLEARED_MANIFESTS = [];
29+
2230
/**
2331
* An array containing all test names for output.
2432
*
@@ -34,8 +42,9 @@ class DefaultTestManifest extends BaseTestManifest
3442
public function __construct($manifestPath, $testPath)
3543
{
3644
$this->manifestPath = $manifestPath . DIRECTORY_SEPARATOR . 'testManifest.txt';
45+
$this->cleanManifest($this->manifestPath);
3746
parent::__construct($testPath, self::DEFAULT_CONFIG);
38-
$fileResource = fopen($this->manifestPath, 'w');
47+
$fileResource = fopen($this->manifestPath, 'a');
3948
fclose($fileResource);
4049
}
4150

@@ -67,4 +76,26 @@ public function generate($nodes = null)
6776

6877
fclose($fileResource);
6978
}
79+
80+
/**
81+
* Function which checks the path for an existing test manifest and clears if the file has not already been cleared
82+
* during current runtime.
83+
*
84+
* @param string $path
85+
* @return void
86+
*/
87+
private function cleanManifest($path)
88+
{
89+
// if we have already cleared the file then simply return
90+
if (in_array($path, self::$CLEARED_MANIFESTS)) {
91+
return;
92+
}
93+
94+
// if the file exists remove
95+
if (file_exists($path)) {
96+
unlink($path);
97+
}
98+
99+
self::$CLEARED_MANIFESTS[] = $path;
100+
}
70101
}

‎src/Magento/FunctionalTestingFramework/Util/Manifest/SingleRunTestManifest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public function __construct($manifestPath, $testPath)
1919
{
2020
parent::__construct($manifestPath, $testPath);
2121
$this->runTypeConfig = self::SINGLE_RUN_CONFIG;
22-
$fileResource = fopen($this->manifestPath, 'w');
22+
$fileResource = fopen($this->manifestPath, 'a');
2323
fclose($fileResource);
2424
}
2525

‎src/Magento/FunctionalTestingFramework/Util/TestGenerator.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,12 @@ private function createCestFile($testPhp, $filename)
135135
*
136136
* @param string $runConfig
137137
* @param int $nodes
138+
* @param TestObject[] $testsToIgnore
138139
* @return void
139140
* @throws TestReferenceException
140141
* @throws \Exception
141142
*/
142-
public function createAllTestFiles($runConfig = null, $nodes = null)
143+
public function createAllTestFiles($runConfig = null, $nodes = null, $testsToIgnore = [])
143144
{
144145
DirSetupUtil::createGroupDir($this->exportDirectory);
145146

@@ -149,8 +150,8 @@ public function createAllTestFiles($runConfig = null, $nodes = null)
149150
$this->exportDirectory,
150151
$runConfig
151152
);
152-
$testPhpArray = $this->assembleAllTestPhp($testManifest, $nodes);
153153

154+
$testPhpArray = $this->assembleAllTestPhp($testManifest, $nodes, $testsToIgnore);
154155
foreach ($testPhpArray as $testPhpFile) {
155156
$this->createCestFile($testPhpFile[1], $testPhpFile[0]);
156157
}
@@ -196,14 +197,16 @@ private function assembleTestPhp($testObject)
196197
*
197198
* @param BaseTestManifest $testManifest
198199
* @param int $nodes
200+
* @param TestObject[] $testsToIgnore
199201
* @return array
200202
* @throws TestReferenceException
201203
* @throws \Exception
202204
*/
203-
private function assembleAllTestPhp($testManifest, $nodes)
205+
private function assembleAllTestPhp($testManifest, $nodes, $testsToIgnore)
204206
{
205207
/** @var TestObject[] $testObjects */
206208
$testObjects = $this->loadAllTestObjects();
209+
$testObjects = array_diff_key($testObjects, $testsToIgnore);
207210
$cestPhpArray = [];
208211

209212
foreach ($testObjects as $test) {

0 commit comments

Comments
 (0)
Please sign in to comment.