Skip to content

Commit a1bc07c

Browse files
committed
MQE-1980: dependency static test fix and static test refactoring
1 parent f6bbe8c commit a1bc07c

File tree

7 files changed

+204
-153
lines changed

7 files changed

+204
-153
lines changed

src/Magento/FunctionalTestingFramework/StaticCheck/TestDependencyCheck.php

+59-142
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,8 @@
66

77
namespace Magento\FunctionalTestingFramework\StaticCheck;
88

9-
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
10-
use Magento\FunctionalTestingFramework\DataGenerator\Handlers\DataObjectHandler;
11-
use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException;
129
use Magento\FunctionalTestingFramework\Exceptions\XmlException;
13-
use Magento\FunctionalTestingFramework\Page\Handlers\PageObjectHandler;
14-
use Magento\FunctionalTestingFramework\Page\Handlers\SectionObjectHandler;
15-
use Magento\FunctionalTestingFramework\Test\Handlers\ActionGroupObjectHandler;
16-
use Magento\FunctionalTestingFramework\Test\Handlers\TestObjectHandler;
1710
use Magento\FunctionalTestingFramework\Test\Objects\ActionObject;
18-
use Magento\FunctionalTestingFramework\Util\TestGenerator;
1911
use Symfony\Component\Console\Input\InputInterface;
2012
use Symfony\Component\Finder\Finder;
2113
use Exception;
@@ -24,13 +16,11 @@
2416
/**
2517
* Class TestDependencyCheck
2618
* @package Magento\FunctionalTestingFramework\StaticCheck
27-
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2819
*/
2920
class TestDependencyCheck implements StaticCheckInterface
3021
{
3122
const EXTENDS_REGEX_PATTERN = '/extends=["\']([^\'"]*)/';
3223
const ACTIONGROUP_REGEX_PATTERN = '/ref=["\']([^\'"]*)/';
33-
const ACTIONGROUP_ARGUMENT_REGEX_PATTERN = '/<argument[^\/>]*name="([^"\']*)/';
3424

3525
const ERROR_LOG_FILENAME = 'mftf-dependency-checks';
3626
const ERROR_LOG_MESSAGE = 'MFTF File Dependency Check';
@@ -83,6 +73,13 @@ class TestDependencyCheck implements StaticCheckInterface
8373
*/
8474
private $allEntities = [];
8575

76+
/**
77+
* ScriptUtil instance
78+
*
79+
* @var ScriptUtil
80+
*/
81+
private $scriptUtil;
82+
8683
/**
8784
* Checks test dependencies, determined by references in tests versus the dependencies listed in the Magento module
8885
*
@@ -92,7 +89,8 @@ class TestDependencyCheck implements StaticCheckInterface
9289
*/
9390
public function execute(InputInterface $input)
9491
{
95-
$allModules = ScriptUtil::getAllModulePaths();
92+
$this->scriptUtil = new ScriptUtil();
93+
$allModules = $this->scriptUtil->getAllModulePaths();
9694

9795
if (!class_exists('\Magento\Framework\Component\ComponentRegistrar')) {
9896
return "TEST DEPENDENCY CHECK ABORTED: MFTF must be attached or pointing to Magento codebase.";
@@ -108,17 +106,17 @@ public function execute(InputInterface $input)
108106
DIRECTORY_SEPARATOR . 'Data' . DIRECTORY_SEPARATOR,
109107
];
110108
// These files can contain references to other modules.
111-
$testXmlFiles = ScriptUtil::getModuleXmlFilesByScope($allModules, $filePaths[0]);
112-
$actionGroupXmlFiles = ScriptUtil::getModuleXmlFilesByScope($allModules, $filePaths[1]);
113-
$dataXmlFiles= ScriptUtil::getModuleXmlFilesByScope($allModules, $filePaths[2]);
109+
$testXmlFiles = $this->scriptUtil->getModuleXmlFilesByScope($allModules, $filePaths[0]);
110+
$actionGroupXmlFiles = $this->scriptUtil->getModuleXmlFilesByScope($allModules, $filePaths[1]);
111+
$dataXmlFiles= $this->scriptUtil->getModuleXmlFilesByScope($allModules, $filePaths[2]);
114112

115113
$this->errors = [];
116114
$this->errors += $this->findErrorsInFileSet($testXmlFiles);
117115
$this->errors += $this->findErrorsInFileSet($actionGroupXmlFiles);
118116
$this->errors += $this->findErrorsInFileSet($dataXmlFiles);
119117

120118
// hold on to the output and print any errors to a file
121-
$this->output = ScriptUtil::printErrorsToFile(
119+
$this->output = $this->scriptUtil->printErrorsToFile(
122120
$this->errors,
123121
self::ERROR_LOG_FILENAME,
124122
self::ERROR_LOG_MESSAGE
@@ -147,17 +145,16 @@ public function getOutput()
147145
* Finds all reference errors in given set of files
148146
* @param Finder $files
149147
* @return array
150-
* @throws TestReferenceException
151148
* @throws XmlException
152149
*/
153150
private function findErrorsInFileSet($files)
154151
{
155152
$testErrors = [];
156153
foreach ($files as $filePath) {
157-
$modulePath = dirname(dirname(dirname(dirname($filePath))));
158-
$moduleFullName = array_search($modulePath, $this->moduleNameToPath) ?? null;
154+
$this->allEntities = [];
155+
$moduleName = $this->getModuleName($filePath);
159156
// Not a module, is either dev/tests/acceptance or loose folder with test materials
160-
if ($moduleFullName == null) {
157+
if ($moduleName == null) {
161158
continue;
162159
}
163160

@@ -172,108 +169,37 @@ private function findErrorsInFileSet($files)
172169
$braceReferences[1] = array_unique($braceReferences[1]);
173170
$braceReferences[2] = array_filter(array_unique($braceReferences[2]));
174171

175-
// resolve data entity references
176-
$this->resolveDataEntityReferences($braceReferences[0], $contents);
172+
// resolve entity references
173+
$this->allEntities = array_merge(
174+
$this->allEntities,
175+
$this->scriptUtil->resolveEntityReferences($braceReferences[0], $contents)
176+
);
177177

178-
//resolve entity references
179-
$this->resolveParametrizedReferences($braceReferences[2], $contents);
178+
// resolve parameterized references
179+
$this->allEntities = array_merge(
180+
$this->allEntities,
181+
$this->scriptUtil->resolveParametrizedReferences($braceReferences[2], $contents)
182+
);
180183

181-
// Check actionGroup references
182-
$this->resolveEntityReferences($actionGroupReferences[1]);
184+
// resolve entity by names
185+
$this->allEntities = array_merge(
186+
$this->allEntities,
187+
$this->scriptUtil->resolveEntityByNames($actionGroupReferences[1])
188+
);
183189

184-
// Check extended objects
185-
$this->resolveEntityReferences($extendReferences[1]);
190+
// resolve entity by names
191+
$this->allEntities = array_merge(
192+
$this->allEntities,
193+
$this->scriptUtil->resolveEntityByNames($extendReferences[1])
194+
);
186195

187196
// Find violating references and set error output
188-
$violatingReferences = $this->findViolatingReferences($moduleFullName);
189-
$testErrors = $this->setErrorOutput($violatingReferences, $filePath);
197+
$violatingReferences = $this->findViolatingReferences($moduleName);
198+
$testErrors = array_merge($testErrors, $this->setErrorOutput($violatingReferences, $filePath));
190199
}
191200
return $testErrors;
192201
}
193202

194-
/**
195-
* Drill down into params in {{ref.params('string', $data.key$, entity.reference)}}
196-
* and resolve references.
197-
*
198-
* @param array $braceReferences
199-
* @param string $contents
200-
* @return void
201-
* @throws XmlException
202-
*/
203-
private function resolveParametrizedReferences($braceReferences, $contents)
204-
{
205-
foreach ($braceReferences as $parameterizedReference) {
206-
preg_match(
207-
ActionObject::ACTION_ATTRIBUTE_VARIABLE_REGEX_PARAMETER,
208-
$parameterizedReference,
209-
$arguments
210-
);
211-
$splitArguments = explode(',', ltrim(rtrim($arguments[0], ")"), "("));
212-
foreach ($splitArguments as $argument) {
213-
// Do nothing for 'string' or $persisted.data$
214-
if (preg_match(ActionObject::STRING_PARAMETER_REGEX, $argument)) {
215-
continue;
216-
} elseif (preg_match(TestGenerator::PERSISTED_OBJECT_NOTATION_REGEX, $argument)) {
217-
continue;
218-
}
219-
// trim `data.field` to `data`
220-
preg_match('/([^.]+)/', $argument, $entityName);
221-
// Double check that {{data.field}} isn't an argument for an ActionGroup
222-
$entity = $this->findEntity($entityName[1]);
223-
preg_match_all(self::ACTIONGROUP_ARGUMENT_REGEX_PATTERN, $contents, $possibleArgument);
224-
if (array_search($entityName[1], $possibleArgument[1]) !== false) {
225-
continue;
226-
}
227-
if ($entity !== null) {
228-
$this->allEntities[$entity->getName()] = $entity;
229-
}
230-
}
231-
}
232-
}
233-
234-
/**
235-
* Check `data` entities in {{data.field}} or {{data.field('param')}} and resolve references
236-
*
237-
* @param array $braceReferences
238-
* @param string $contents
239-
* @return void
240-
* @throws XmlException
241-
242-
*/
243-
private function resolveDataEntityReferences($braceReferences, $contents)
244-
{
245-
foreach ($braceReferences as $reference) {
246-
// trim `{{data.field}}` to `data`
247-
preg_match('/{{([^.]+)/', $reference, $entityName);
248-
// Double check that {{data.field}} isn't an argument for an ActionGroup
249-
$entity = $this->findEntity($entityName[1]);
250-
preg_match_all(self::ACTIONGROUP_ARGUMENT_REGEX_PATTERN, $contents, $possibleArgument);
251-
if (array_search($entityName[1], $possibleArgument[1]) !== false) {
252-
continue;
253-
}
254-
if ($entity !== null) {
255-
$this->allEntities[$entity->getName()] = $entity;
256-
}
257-
}
258-
}
259-
260-
/**
261-
* Resolve entity references
262-
*
263-
* @param array $references
264-
* @return void
265-
* @throws XmlException
266-
*/
267-
private function resolveEntityReferences($references)
268-
{
269-
foreach ($references as $reference) {
270-
$entity = $this->findEntity($reference);
271-
if ($entity !== null) {
272-
$this->allEntities[$entity->getName()] = $entity;
273-
}
274-
}
275-
}
276-
277203
/**
278204
* Find violating references
279205
*
@@ -351,7 +277,10 @@ private function buildComposerDependencyList()
351277
$flattenedDependencies = [];
352278

353279
foreach ($this->moduleNameToPath as $moduleName => $pathToModule) {
354-
$composerData = json_decode(file_get_contents($pathToModule . DIRECTORY_SEPARATOR . "composer.json"), true);
280+
$composerData = json_decode(
281+
file_get_contents($pathToModule . DIRECTORY_SEPARATOR . "composer.json"),
282+
true
283+
);
355284
$this->allDependencies[$moduleName] = $composerData['require'];
356285
}
357286
foreach ($this->allDependencies as $moduleName => $dependencies) {
@@ -403,43 +332,31 @@ private function getModuleDependenciesFromReferences($array)
403332
// Should it append ALL filenames, including merges?
404333
$allFiles = explode(",", $item->getFilename());
405334
foreach ($allFiles as $file) {
406-
$modulePath = dirname(dirname(dirname(dirname($file))));
407-
$fullModuleName = array_search($modulePath, $this->moduleNameToPath);
408-
$composerModuleName = $this->moduleNameToComposerName[$fullModuleName];
409-
$filenames[$item->getName()][] = $composerModuleName;
335+
$moduleName = $this->getModuleName($file);
336+
if (isset($this->moduleNameToComposerName[$moduleName])) {
337+
$composerModuleName = $this->moduleNameToComposerName[$moduleName];
338+
$filenames[$item->getName()][] = $composerModuleName;
339+
}
410340
}
411341
}
412342
return $filenames;
413343
}
414344

415345
/**
416-
* Attempts to find any MFTF entity by its name. Returns null if none are found.
417-
* @param string $name
418-
* @return mixed
419-
* @throws XmlException
346+
* Return module name for a file path
347+
*
348+
* @param string $filePath
349+
* @return string|null
420350
*/
421-
private function findEntity($name)
351+
private function getModuleName($filePath)
422352
{
423-
if ($name == '_ENV' || $name == '_CREDS') {
424-
return null;
425-
}
426-
427-
if (DataObjectHandler::getInstance()->getObject($name)) {
428-
return DataObjectHandler::getInstance()->getObject($name);
429-
} elseif (PageObjectHandler::getInstance()->getObject($name)) {
430-
return PageObjectHandler::getInstance()->getObject($name);
431-
} elseif (SectionObjectHandler::getInstance()->getObject($name)) {
432-
return SectionObjectHandler::getInstance()->getObject($name);
433-
}
434-
435-
try {
436-
return ActionGroupObjectHandler::getInstance()->getObject($name);
437-
} catch (TestReferenceException $e) {
438-
}
439-
try {
440-
return TestObjectHandler::getInstance()->getObject($name);
441-
} catch (TestReferenceException $e) {
353+
$moduleName = null;
354+
foreach ($this->moduleNameToPath as $name => $path) {
355+
if (strpos($filePath, $path) !== false) {
356+
$moduleName = $name;
357+
break;
358+
}
442359
}
443-
return null;
360+
return $moduleName;
444361
}
445362
}

src/Magento/FunctionalTestingFramework/Upgrade/RemoveModuleFileInSuiteFiles.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,16 @@ class RemoveModuleFileInSuiteFiles implements UpgradeInterface
6464
*/
6565
public function execute(InputInterface $input, OutputInterface $output)
6666
{
67+
$scriptUtil = new ScriptUtil();
6768
$this->setOutputStyle($input, $output);
6869
$this->output = $output;
6970
$testPaths[] = $input->getArgument('path');
7071
if (empty($testPaths[0])) {
71-
$testPaths = ScriptUtil::getAllModulePaths();
72+
$testPaths = $scriptUtil->getAllModulePaths();
7273
}
7374

7475
// Get module suite xml files
75-
$xmlFiles = ScriptUtil::getModuleXmlFilesByScope($testPaths, 'Suite');
76+
$xmlFiles = $scriptUtil->getModuleXmlFilesByScope($testPaths, 'Suite');
7677
$this->processXmlFiles($xmlFiles);
7778

7879
return ("Removed module file reference in {$this->testsUpdated} suite file(s).");

src/Magento/FunctionalTestingFramework/Upgrade/RenameMetadataFiles.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ class RenameMetadataFiles implements UpgradeInterface
2626
*/
2727
public function execute(InputInterface $input, OutputInterface $output)
2828
{
29+
$scriptUtil = new ScriptUtil();
2930
$testPaths[] = $input->getArgument('path');
3031
if (empty($testPaths[0])) {
31-
$testPaths = ScriptUtil::getAllModulePaths();
32+
$testPaths = $scriptUtil->getAllModulePaths();
3233
}
3334

3435
foreach ($testPaths as $testsPath) {

src/Magento/FunctionalTestingFramework/Upgrade/SplitMultipleEntitiesFiles.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,17 @@ class SplitMultipleEntitiesFiles implements UpgradeInterface
6969
*/
7070
public function execute(InputInterface $input, OutputInterface $output)
7171
{
72+
$scriptUtil = new ScriptUtil();
7273
$this->output = $output;
7374
$this->testsUpdated = 0;
7475
$testPaths[] = $input->getArgument('path');
7576
if (empty($testPaths[0])) {
76-
$testPaths = ScriptUtil::getAllModulePaths();
77+
$testPaths = $scriptUtil->getAllModulePaths();
7778
}
7879

7980
// Process module xml files
8081
foreach ($this->entityCategories as $type => $urn) {
81-
$xmlFiles = ScriptUtil::getModuleXmlFilesByScope($testPaths, $type);
82+
$xmlFiles = $scriptUtil->getModuleXmlFilesByScope($testPaths, $type);
8283
$this->processXmlFiles($xmlFiles, $type, $urn);
8384
}
8485

src/Magento/FunctionalTestingFramework/Upgrade/UpdateAssertionSchema.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ class UpdateAssertionSchema implements UpgradeInterface
2828
*/
2929
public function execute(InputInterface $input, OutputInterface $output)
3030
{
31+
$scriptUtil = new ScriptUtil();
3132
$testPaths[] = $input->getArgument('path');
3233
if (empty($testPaths[0])) {
33-
$testPaths = ScriptUtil::getAllModulePaths();
34+
$testPaths = $scriptUtil->getAllModulePaths();
3435
}
3536

3637
$testsUpdated = 0;

src/Magento/FunctionalTestingFramework/Upgrade/UpdateTestSchemaPaths.php

+3-2
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,17 @@ class UpdateTestSchemaPaths implements UpgradeInterface
5757
*/
5858
public function execute(InputInterface $input, OutputInterface $output)
5959
{
60+
$scriptUtil = new ScriptUtil();
6061
$this->output = $output;
6162
$this->testsUpdated = 0;
6263
$testPaths[] = $input->getArgument('path');
6364
if (empty($testPaths[0])) {
64-
$testPaths = ScriptUtil::getAllModulePaths();
65+
$testPaths = $scriptUtil->getAllModulePaths();
6566
}
6667

6768
// Process module xml files
6869
foreach ($this->typeToUrns as $type => $urn) {
69-
$xmlFiles = ScriptUtil::getModuleXmlFilesByScope($testPaths, $type);
70+
$xmlFiles = $scriptUtil->getModuleXmlFilesByScope($testPaths, $type);
7071
$this->processXmlFiles($xmlFiles, $urn);
7172
}
7273

0 commit comments

Comments
 (0)