From c6025c464df14abbb080aacf6bd2231fcae3912f Mon Sep 17 00:00:00 2001 From: "andrii.zinkevych" Date: Fri, 23 Jul 2021 11:08:39 +0300 Subject: [PATCH 1/3] 33299: Eliminated AspectMock usage from SuiteGeneratorTest.php --- .../Suite/SuiteGeneratorTest.php | 218 +++++++++++------- .../Suite/Service/SuiteGeneratorService.php | 151 ++++++++++++ .../Suite/SuiteGenerator.php | 82 +------ 3 files changed, 289 insertions(+), 162 deletions(-) create mode 100644 src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php index 136b32e2a..a7178c624 100644 --- a/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php @@ -3,12 +3,15 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +declare(strict_types=1); + namespace tests\unit\Magento\FunctionalTestFramework\Suite; -use AspectMock\Test as AspectMock; +use Exception; use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException; -use Magento\FunctionalTestingFramework\ObjectManager\ObjectManager; +use Magento\FunctionalTestingFramework\ObjectManager; use Magento\FunctionalTestingFramework\ObjectManagerFactory; +use Magento\FunctionalTestingFramework\Suite\Service\SuiteGeneratorService; use Magento\FunctionalTestingFramework\Suite\SuiteGenerator; use Magento\FunctionalTestingFramework\Suite\Generators\GroupClassGenerator; use Magento\FunctionalTestingFramework\Suite\Handlers\SuiteObjectHandler; @@ -18,41 +21,31 @@ use Magento\FunctionalTestingFramework\Test\Parsers\TestDataParser; use Magento\FunctionalTestingFramework\Util\GenerationErrorHandler; use Magento\FunctionalTestingFramework\Util\Manifest\DefaultTestManifest; +use ReflectionProperty; use tests\unit\Util\MagentoTestCase; use Magento\FunctionalTestingFramework\Util\Manifest\TestManifestFactory; use tests\unit\Util\SuiteDataArrayBuilder; use tests\unit\Util\TestDataArrayBuilder; use tests\unit\Util\TestLoggingUtil; -use tests\unit\Util\MockModuleResolverBuilder; class SuiteGeneratorTest extends MagentoTestCase { - /** - * Setup entry append and clear for Suite Generator - */ - public static function setUpBeforeClass(): void - { - AspectMock::double(SuiteGenerator::class, [ - 'clearPreviousSessionConfigEntries' => null, - 'appendEntriesToConfig' => null - ]); - } - /** * Before test functionality * @return void */ - public function setUp(): void + protected function setUp(): void { TestLoggingUtil::getInstance()->setMockLoggingUtil(); - $resolverMock = new MockModuleResolverBuilder(); - $resolverMock->setup(); } /** - * Tests generating a single suite given a set of parsed test data + * Tests generating a single suite given a set of parsed test data. + * + * @return void + * @throws Exception */ - public function testGenerateSuite() + public function testGenerateSuite(): void { $suiteDataArrayBuilder = new SuiteDataArrayBuilder(); $mockData = $suiteDataArrayBuilder @@ -74,20 +67,23 @@ public function testGenerateSuite() // parse and generate suite object with mocked data $mockSuiteGenerator = SuiteGenerator::getInstance(); - $mockSuiteGenerator->generateSuite("basicTestSuite"); + $mockSuiteGenerator->generateSuite('basicTestSuite'); // assert that expected suite is generated TestLoggingUtil::getInstance()->validateMockLogStatement( 'info', - "suite generated", - ['suite' => 'basicTestSuite', 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . "basicTestSuite"] + 'suite generated', + ['suite' => 'basicTestSuite', 'relative_path' => '_generated' . DIRECTORY_SEPARATOR . 'basicTestSuite'] ); } /** - * Tests generating all suites given a set of parsed test data + * Tests generating all suites given a set of parsed test data. + * + * @return void + * @throws Exception */ - public function testGenerateAllSuites() + public function testGenerateAllSuites(): void { $suiteDataArrayBuilder = new SuiteDataArrayBuilder(); $mockData = $suiteDataArrayBuilder @@ -108,22 +104,25 @@ public function testGenerateAllSuites() $this->setMockTestAndSuiteParserOutput($mockTestData, $mockData); // parse and retrieve suite object with mocked data - $exampleTestManifest = new DefaultTestManifest([], "sample" . DIRECTORY_SEPARATOR . "path"); + $exampleTestManifest = new DefaultTestManifest([], 'sample' . DIRECTORY_SEPARATOR . 'path'); $mockSuiteGenerator = SuiteGenerator::getInstance(); $mockSuiteGenerator->generateAllSuites($exampleTestManifest); // assert that expected suites are generated TestLoggingUtil::getInstance()->validateMockLogStatement( 'info', - "suite generated", - ['suite' => 'basicTestSuite', 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . "basicTestSuite"] + 'suite generated', + ['suite' => 'basicTestSuite', 'relative_path' => '_generated' . DIRECTORY_SEPARATOR . 'basicTestSuite'] ); } /** - * Tests attempting to generate a suite with no included/excluded tests and no hooks + * Tests attempting to generate a suite with no included/excluded tests and no hooks. + * + * @return void + * @throws Exception */ - public function testGenerateEmptySuite() + public function testGenerateEmptySuite(): void { $testDataArrayBuilder = new TestDataArrayBuilder(); $mockTestData = $testDataArrayBuilder @@ -142,17 +141,20 @@ public function testGenerateEmptySuite() $this->setMockTestAndSuiteParserOutput($mockTestData, $mockData); // set expected error message - $this->expectExceptionMessage("Suite basicTestSuite is not defined in xml or is invalid"); + $this->expectExceptionMessage('Suite basicTestSuite is not defined in xml or is invalid'); // parse and generate suite object with mocked data $mockSuiteGenerator = SuiteGenerator::getInstance(); - $mockSuiteGenerator->generateSuite("basicTestSuite"); + $mockSuiteGenerator->generateSuite('basicTestSuite'); } /** - * Tests generating all suites with a suite containing invalid test reference + * Tests generating all suites with a suite containing invalid test reference. + * + * @return void + * @throws TestReferenceException */ - public function testInvalidSuiteTestPair() + public function testInvalidSuiteTestPair(): void { // Mock Suite1 => Test1 and Suite2 => Test2 $suiteDataArrayBuilder = new SuiteDataArrayBuilder(); @@ -198,9 +200,12 @@ public function testInvalidSuiteTestPair() } /** - * Tests generating all suites with a non-existing suite + * Tests generating all suites with a non-existing suite. + * + * @return void + * @throws TestReferenceException */ - public function testNonExistentSuiteTestPair() + public function testNonExistentSuiteTestPair(): void { $testDataArrayBuilder = new TestDataArrayBuilder(); $mockSimpleTest = $testDataArrayBuilder @@ -227,9 +232,12 @@ public function testNonExistentSuiteTestPair() } /** - * Tests generating split suites for parallel test generation + * Tests generating split suites for parallel test generation. + * + * @return void + * @throws TestReferenceException */ - public function testGenerateSplitSuiteFromTest() + public function testGenerateSplitSuiteFromTest(): void { $suiteDataArrayBuilder = new SuiteDataArrayBuilder(); $mockSuiteData = $suiteDataArrayBuilder @@ -272,8 +280,8 @@ public function testGenerateSplitSuiteFromTest() // assert last split suite group generated TestLoggingUtil::getInstance()->validateMockLogStatement( 'info', - "suite generated", - ['suite' => 'mockSuite_1_G', 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . "mockSuite_1_G"] + 'suite generated', + ['suite' => 'mockSuite_1_G', 'relative_path' => '_generated' . DIRECTORY_SEPARATOR . 'mockSuite_1_G'] ); } @@ -282,75 +290,117 @@ public function testGenerateSplitSuiteFromTest() * * @param array $testData * @param array $suiteData - * @throws \Exception + * @throws Exception + */ + private function setMockTestAndSuiteParserOutput(array $testData, array $suiteData): void + { + $this->clearMockResolverProperties(); + $mockSuiteGeneratorService = $this->createMock(SuiteGeneratorService::class); + $mockSuiteGeneratorService + ->method('clearPreviousSessionConfigEntries') + ->willReturn(null); + + $mockSuiteGeneratorService + ->method('appendEntriesToConfig') + ->willReturn(null); + + $suiteGeneratorServiceProperty = new ReflectionProperty(SuiteGeneratorService::class, 'INSTANCE'); + $suiteGeneratorServiceProperty->setAccessible(true); + $suiteGeneratorServiceProperty->setValue($mockSuiteGeneratorService); + + $mockDataParser = $this->createMock(TestDataParser::class); + $mockDataParser + ->method('readTestData') + ->willReturn($testData); + + $mockSuiteDataParser = $this->createMock(SuiteDataParser::class); + $mockSuiteDataParser + ->method('readSuiteData') + ->willReturn($suiteData); + + $mockGroupClass = $this->createMock(GroupClassGenerator::class); + $mockGroupClass + ->method('generateGroupClass') + ->willReturn('namespace'); + + $objectManager = ObjectManagerFactory::getObjectManager(); + + $objectManagerMockInstance = $this->createMock(ObjectManager::class); + $objectManagerMockInstance + ->method('create') + ->will( + $this->returnCallback( + function (string $class, array $arguments = []) use ( + $mockDataParser, + $mockSuiteDataParser, + $mockGroupClass, + $objectManager + ) { + if ($class == TestDataParser::class) { + return $mockDataParser; + } + if ($class == SuiteDataParser::class) { + return $mockSuiteDataParser; + } + if ($class == GroupClassGenerator::class) { + return $mockGroupClass; + } + + return $objectManager->create($class, $arguments); + } + ) + ); + + $objectManagerProperty = new ReflectionProperty(ObjectManager::class, 'instance'); + $objectManagerProperty->setAccessible(true); + $objectManagerProperty->setValue($objectManagerMockInstance); + } + + /** + * Function used to clear mock properties. + * + * @return void */ - private function setMockTestAndSuiteParserOutput($testData, $suiteData) + private function clearMockResolverProperties(): void { - $property = new \ReflectionProperty(SuiteGenerator::class, 'instance'); + $property = new ReflectionProperty(SuiteGenerator::class, 'instance'); $property->setAccessible(true); $property->setValue(null); // clear test object handler value to inject parsed content - $property = new \ReflectionProperty(TestObjectHandler::class, 'testObjectHandler'); + $property = new ReflectionProperty(TestObjectHandler::class, 'testObjectHandler'); $property->setAccessible(true); $property->setValue(null); // clear suite object handler value to inject parsed content - $property = new \ReflectionProperty(SuiteObjectHandler::class, 'instance'); + $property = new ReflectionProperty(SuiteObjectHandler::class, 'instance'); $property->setAccessible(true); $property->setValue(null); - - $mockDataParser = AspectMock::double(TestDataParser::class, ['readTestData' => $testData])->make(); - $mockSuiteDataParser = AspectMock::double(SuiteDataParser::class, ['readSuiteData' => $suiteData])->make(); - $mockGroupClass = AspectMock::double( - GroupClassGenerator::class, - ['generateGroupClass' => 'namespace'] - )->make(); - $mockSuiteClass = AspectMock::double(SuiteGenerator::class, ['generateRelevantGroupTests' => null])->make(); - $instance = AspectMock::double( - ObjectManager::class, - ['create' => function ($clazz) use ( - $mockDataParser, - $mockSuiteDataParser, - $mockGroupClass, - $mockSuiteClass - ) { - if ($clazz == TestDataParser::class) { - return $mockDataParser; - } - if ($clazz == SuiteDataParser::class) { - return $mockSuiteDataParser; - } - if ($clazz == GroupClassGenerator::class) { - return $mockGroupClass; - } - if ($clazz == SuiteGenerator::class) { - return $mockSuiteClass; - } - }] - )->make(); - // bypass the private constructor - AspectMock::double(ObjectManagerFactory::class, ['getObjectManager' => $instance]); - - $property = new \ReflectionProperty(SuiteGenerator::class, 'groupClassGenerator'); - $property->setAccessible(true); - $property->setValue($instance, $instance); } /** - * clean up function runs after each test + * @inheritDoc */ - public function tearDown(): void + protected function tearDown(): void { GenerationErrorHandler::getInstance()->reset(); } /** - * clean up function runs after all tests + * @inheritDoc */ public static function tearDownAfterClass(): void { - TestLoggingUtil::getInstance()->clearMockLoggingUtil(); parent::tearDownAfterClass(); + + $objectManagerProperty = new ReflectionProperty(ObjectManager::class, 'instance'); + $objectManagerProperty->setAccessible(true); + $objectManagerProperty->setValue(null); + + $suiteGeneratorServiceProperty = new ReflectionProperty(SuiteGeneratorService::class, 'INSTANCE'); + $suiteGeneratorServiceProperty->setAccessible(true); + $suiteGeneratorServiceProperty->setValue(null); + + TestLoggingUtil::getInstance()->clearMockLoggingUtil(); } } diff --git a/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php b/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php new file mode 100644 index 000000000..cec4b4997 --- /dev/null +++ b/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php @@ -0,0 +1,151 @@ + $entry) { + if (preg_match('/(Group\\\\.*)/', $entry)) { + unset($newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG][$key]); + } + } + + // needed for proper yml file generation based on indices + $newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG] = + array_values($newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG]); + } + + if (array_key_exists(self::YAML_GROUPS_TAG, $newYmlArray)) { + unset($newYmlArray[self::YAML_GROUPS_TAG]); + } + + $ymlText = self::YAML_COPYRIGHT_TEXT . Yaml::dump($newYmlArray, 10); + file_put_contents(self::getYamlConfigFilePath() . self::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); + } + + + /** + * Function which accepts a suite name and suite path and appends a new group entry to the codeception.yml.dist + * file in order to register the set of tests as a new group. Also appends group object location if required + * by suite. + * + * @param string $suiteName + * @param string $suitePath + * @param string $groupNamespace + * + * @return void + * @throws TestFrameworkException + */ + public function appendEntriesToConfig(string $suiteName, string $suitePath, string $groupNamespace) + { + $relativeSuitePath = substr($suitePath, strlen(TESTS_BP)); + $relativeSuitePath = ltrim($relativeSuitePath, DIRECTORY_SEPARATOR); + $ymlArray = self::getYamlFileContents(); + + if (!array_key_exists(self::YAML_GROUPS_TAG, $ymlArray)) { + $ymlArray[self::YAML_GROUPS_TAG]= []; + } + + if ($groupNamespace) { + $ymlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG][] = $groupNamespace; + } + + $ymlArray[self::YAML_GROUPS_TAG][$suiteName] = [$relativeSuitePath]; + $ymlText = self::YAML_COPYRIGHT_TEXT . Yaml::dump($ymlArray, 10); + file_put_contents(self::getYamlConfigFilePath() . self::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); + } + + /** + * Function to return contents of codeception.yml file for config changes. + * + * @return array + * @throws TestFrameworkException + */ + private static function getYamlFileContents(): array + { + $configYmlFile = self::getYamlConfigFilePath() . self::YAML_CODECEPTION_CONFIG_FILENAME; + $defaultConfigYmlFile = self::getYamlConfigFilePath() . self::YAML_CODECEPTION_DIST_FILENAME; + $ymlContents = null; + + if (file_exists($configYmlFile)) { + $ymlContents = file_get_contents($configYmlFile); + } else { + $ymlContents = file_get_contents($defaultConfigYmlFile); + } + + return Yaml::parse($ymlContents) ?? []; + } + + /** + * Static getter for the Config yml filepath (as path cannot be stored in a const). + * + * @return string + * @throws TestFrameworkException + */ + private static function getYamlConfigFilePath() + { + return FilePathFormatter::format(TESTS_BP); + } +} \ No newline at end of file diff --git a/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php b/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php index 1f8fec586..57f70238c 100644 --- a/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php +++ b/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php @@ -8,12 +8,12 @@ use Magento\FunctionalTestingFramework\Exceptions\Collector\ExceptionCollector; use Magento\FunctionalTestingFramework\Exceptions\FastFailException; -use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException; use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException; use Magento\FunctionalTestingFramework\Exceptions\XmlException; use Magento\FunctionalTestingFramework\Suite\Generators\GroupClassGenerator; use Magento\FunctionalTestingFramework\Suite\Handlers\SuiteObjectHandler; use Magento\FunctionalTestingFramework\Suite\Objects\SuiteObject; +use Magento\FunctionalTestingFramework\Suite\Service\SuiteGeneratorService; use Magento\FunctionalTestingFramework\Test\Handlers\TestObjectHandler; use Magento\FunctionalTestingFramework\Util\Filesystem\DirSetupUtil; use Magento\FunctionalTestingFramework\Util\GenerationErrorHandler; @@ -21,7 +21,6 @@ use Magento\FunctionalTestingFramework\Util\Manifest\BaseTestManifest; use Magento\FunctionalTestingFramework\Util\Path\FilePathFormatter; use Magento\FunctionalTestingFramework\Util\TestGenerator; -use Symfony\Component\Yaml\Yaml; use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig; /** @@ -30,14 +29,6 @@ */ class SuiteGenerator { - const YAML_CODECEPTION_DIST_FILENAME = 'codeception.dist.yml'; - const YAML_CODECEPTION_CONFIG_FILENAME = 'codeception.yml'; - const YAML_GROUPS_TAG = 'groups'; - const YAML_EXTENSIONS_TAG = 'extensions'; - const YAML_ENABLED_TAG = 'enabled'; - const YAML_COPYRIGHT_TEXT = - "# Copyright © Magento, Inc. All rights reserved.\n# See COPYING.txt for license details.\n"; - /** * Singelton Variable Instance. * @@ -268,7 +259,7 @@ private function generateSplitSuiteFromTest($suiteName, $suiteContent) try { $this->generateSuiteFromTest($suiteSplitName, $tests, $suiteName); } catch (FastFailException $e) { - throw $e; + throw $e; } catch (\Exception $e) { // There are suites that include tests that reference tests from other Magento editions // To keep backward compatibility, we will catch such exceptions with no error. @@ -331,21 +322,7 @@ private function generateGroupFile($suiteName, $tests, $originalSuiteName) */ private function appendEntriesToConfig($suiteName, $suitePath, $groupNamespace) { - $relativeSuitePath = substr($suitePath, strlen(TESTS_BP)); - $relativeSuitePath = ltrim($relativeSuitePath, DIRECTORY_SEPARATOR); - - $ymlArray = self::getYamlFileContents(); - if (!array_key_exists(self::YAML_GROUPS_TAG, $ymlArray)) { - $ymlArray[self::YAML_GROUPS_TAG]= []; - } - - if ($groupNamespace) { - $ymlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG][] = $groupNamespace; - } - $ymlArray[self::YAML_GROUPS_TAG][$suiteName] = [$relativeSuitePath]; - - $ymlText = self::YAML_COPYRIGHT_TEXT . Yaml::dump($ymlArray, 10); - file_put_contents(self::getYamlConfigFilePath() . self::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); + SuiteGeneratorService::getInstance()->appendEntriesToConfig($suiteName, $suitePath, $groupNamespace); } /** @@ -356,27 +333,7 @@ private function appendEntriesToConfig($suiteName, $suitePath, $groupNamespace) */ private static function clearPreviousSessionConfigEntries() { - $ymlArray = self::getYamlFileContents(); - $newYmlArray = $ymlArray; - // if the yaml entries haven't already been cleared - if (array_key_exists(self::YAML_EXTENSIONS_TAG, $ymlArray)) { - foreach ($ymlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG] as $key => $entry) { - if (preg_match('/(Group\\\\.*)/', $entry)) { - unset($newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG][$key]); - } - } - - // needed for proper yml file generation based on indices - $newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG] = - array_values($newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG]); - } - - if (array_key_exists(self::YAML_GROUPS_TAG, $newYmlArray)) { - unset($newYmlArray[self::YAML_GROUPS_TAG]); - } - - $ymlText = self::YAML_COPYRIGHT_TEXT . Yaml::dump($newYmlArray, 10); - file_put_contents(self::getYamlConfigFilePath() . self::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); + SuiteGeneratorService::getInstance()->clearPreviousSessionConfigEntries(); } /** @@ -406,37 +363,6 @@ private static function clearPreviousGroupPreconditions() array_map('unlink', glob("$groupFilePath*.php")); } - /** - * Function to return contents of codeception.yml file for config changes. - * - * @return array - */ - private static function getYamlFileContents() - { - $configYmlFile = self::getYamlConfigFilePath() . self::YAML_CODECEPTION_CONFIG_FILENAME; - $defaultConfigYmlFile = self::getYamlConfigFilePath() . self::YAML_CODECEPTION_DIST_FILENAME; - - $ymlContents = null; - if (file_exists($configYmlFile)) { - $ymlContents = file_get_contents($configYmlFile); - } else { - $ymlContents = file_get_contents($defaultConfigYmlFile); - } - - return Yaml::parse($ymlContents) ?? []; - } - - /** - * Static getter for the Config yml filepath (as path cannot be stored in a const) - * - * @return string - * @throws TestFrameworkException - */ - private static function getYamlConfigFilePath() - { - return FilePathFormatter::format(TESTS_BP); - } - /** * Log error and throw collected exceptions * From 73416f085115b6b7420cd9d50646bdfc7375464a Mon Sep 17 00:00:00 2001 From: "andrii.zinkevych" Date: Fri, 23 Jul 2021 14:39:04 +0300 Subject: [PATCH 2/3] 33299: Fixed static-test --- .../Suite/SuiteGeneratorTest.php | 5 +- .../Suite/Service/SuiteGeneratorService.php | 57 ++++++++----------- .../Suite/SuiteGenerator.php | 8 +++ 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php index a7178c624..85afe7cde 100644 --- a/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php @@ -330,7 +330,10 @@ private function setMockTestAndSuiteParserOutput(array $testData, array $suiteDa ->method('create') ->will( $this->returnCallback( - function (string $class, array $arguments = []) use ( + function ( + string $class, + array $arguments = [] + ) use ( $mockDataParser, $mockSuiteDataParser, $mockGroupClass, diff --git a/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php b/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php index cec4b4997..9aed81c5c 100644 --- a/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php +++ b/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php @@ -8,6 +8,7 @@ namespace Magento\FunctionalTestingFramework\Suite\Service; use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException; +use Magento\FunctionalTestingFramework\Suite\SuiteGenerator; use Magento\FunctionalTestingFramework\Util\Path\FilePathFormatter; use Symfony\Component\Yaml\Yaml; @@ -16,15 +17,6 @@ */ class SuiteGeneratorService { - const YAML_CODECEPTION_DIST_FILENAME = 'codeception.dist.yml'; - const YAML_CODECEPTION_CONFIG_FILENAME = 'codeception.yml'; - const YAML_GROUPS_TAG = 'groups'; - const YAML_EXTENSIONS_TAG = 'extensions'; - const YAML_ENABLED_TAG = 'enabled'; - const YAML_COPYRIGHT_TEXT = - "# Copyright © Magento, Inc. All rights reserved.\n# See COPYING.txt for license details.\n"; - - /** * Singleton SuiteGeneratorService Instance. * @@ -65,56 +57,57 @@ public function clearPreviousSessionConfigEntries() $ymlArray = self::getYamlFileContents(); $newYmlArray = $ymlArray; // if the yaml entries haven't already been cleared - if (array_key_exists(self::YAML_EXTENSIONS_TAG, $ymlArray)) { - foreach ($ymlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG] as $key => $entry) { + if (array_key_exists(SuiteGenerator::YAML_EXTENSIONS_TAG, $ymlArray)) { + $ymlEntries = $ymlArray[SuiteGenerator::YAML_EXTENSIONS_TAG][SuiteGenerator::YAML_ENABLED_TAG]; + + foreach ($ymlEntries as $key => $entry) { if (preg_match('/(Group\\\\.*)/', $entry)) { - unset($newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG][$key]); + unset($newYmlArray[SuiteGenerator::YAML_EXTENSIONS_TAG][SuiteGenerator::YAML_ENABLED_TAG][$key]); } } // needed for proper yml file generation based on indices - $newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG] = - array_values($newYmlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG]); + $newYmlArray[SuiteGenerator::YAML_EXTENSIONS_TAG][SuiteGenerator::YAML_ENABLED_TAG] = + array_values($newYmlArray[SuiteGenerator::YAML_EXTENSIONS_TAG][SuiteGenerator::YAML_ENABLED_TAG]); } - if (array_key_exists(self::YAML_GROUPS_TAG, $newYmlArray)) { - unset($newYmlArray[self::YAML_GROUPS_TAG]); + if (array_key_exists(SuiteGenerator::YAML_GROUPS_TAG, $newYmlArray)) { + unset($newYmlArray[SuiteGenerator::YAML_GROUPS_TAG]); } - $ymlText = self::YAML_COPYRIGHT_TEXT . Yaml::dump($newYmlArray, 10); - file_put_contents(self::getYamlConfigFilePath() . self::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); + $ymlText = SuiteGenerator::YAML_COPYRIGHT_TEXT . Yaml::dump($newYmlArray, 10); + file_put_contents(self::getYamlConfigFilePath() . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); } - /** * Function which accepts a suite name and suite path and appends a new group entry to the codeception.yml.dist * file in order to register the set of tests as a new group. Also appends group object location if required * by suite. * - * @param string $suiteName - * @param string $suitePath - * @param string $groupNamespace + * @param string $suiteName + * @param string $suitePath + * @param string|null $groupNamespace * * @return void * @throws TestFrameworkException */ - public function appendEntriesToConfig(string $suiteName, string $suitePath, string $groupNamespace) + public function appendEntriesToConfig(string $suiteName, string $suitePath, ?string $groupNamespace) { $relativeSuitePath = substr($suitePath, strlen(TESTS_BP)); $relativeSuitePath = ltrim($relativeSuitePath, DIRECTORY_SEPARATOR); $ymlArray = self::getYamlFileContents(); - if (!array_key_exists(self::YAML_GROUPS_TAG, $ymlArray)) { - $ymlArray[self::YAML_GROUPS_TAG]= []; + if (!array_key_exists(SuiteGenerator::YAML_GROUPS_TAG, $ymlArray)) { + $ymlArray[SuiteGenerator::YAML_GROUPS_TAG] = []; } if ($groupNamespace) { - $ymlArray[self::YAML_EXTENSIONS_TAG][self::YAML_ENABLED_TAG][] = $groupNamespace; + $ymlArray[SuiteGenerator::YAML_EXTENSIONS_TAG][SuiteGenerator::YAML_ENABLED_TAG][] = $groupNamespace; } - $ymlArray[self::YAML_GROUPS_TAG][$suiteName] = [$relativeSuitePath]; - $ymlText = self::YAML_COPYRIGHT_TEXT . Yaml::dump($ymlArray, 10); - file_put_contents(self::getYamlConfigFilePath() . self::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); + $ymlArray[SuiteGenerator::YAML_GROUPS_TAG][$suiteName] = [$relativeSuitePath]; + $ymlText = SuiteGenerator::YAML_COPYRIGHT_TEXT . Yaml::dump($ymlArray, 10); + file_put_contents(self::getYamlConfigFilePath() . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); } /** @@ -125,8 +118,8 @@ public function appendEntriesToConfig(string $suiteName, string $suitePath, stri */ private static function getYamlFileContents(): array { - $configYmlFile = self::getYamlConfigFilePath() . self::YAML_CODECEPTION_CONFIG_FILENAME; - $defaultConfigYmlFile = self::getYamlConfigFilePath() . self::YAML_CODECEPTION_DIST_FILENAME; + $configYmlFile = self::getYamlConfigFilePath() . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME; + $defaultConfigYmlFile = self::getYamlConfigFilePath() . SuiteGenerator::YAML_CODECEPTION_DIST_FILENAME; $ymlContents = null; if (file_exists($configYmlFile)) { @@ -148,4 +141,4 @@ private static function getYamlConfigFilePath() { return FilePathFormatter::format(TESTS_BP); } -} \ No newline at end of file +} diff --git a/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php b/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php index 57f70238c..37e370242 100644 --- a/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php +++ b/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php @@ -29,6 +29,14 @@ */ class SuiteGenerator { + const YAML_CODECEPTION_DIST_FILENAME = 'codeception.dist.yml'; + const YAML_CODECEPTION_CONFIG_FILENAME = 'codeception.yml'; + const YAML_GROUPS_TAG = 'groups'; + const YAML_EXTENSIONS_TAG = 'extensions'; + const YAML_ENABLED_TAG = 'enabled'; + const YAML_COPYRIGHT_TEXT = + "# Copyright © Magento, Inc. All rights reserved.\n# See COPYING.txt for license details.\n"; + /** * Singelton Variable Instance. * From 74a08921b87b66cb04f90abbccf4d0074e77bde1 Mon Sep 17 00:00:00 2001 From: bohdan-harniuk Date: Fri, 23 Jul 2021 15:16:31 +0300 Subject: [PATCH 3/3] 33299: code refactoring after code review --- .../Suite/SuiteGeneratorTest.php | 16 ++++++++--- .../Suite/Service/SuiteGeneratorService.php | 28 +++++++++++++++---- .../Suite/SuiteGenerator.php | 8 +++--- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php b/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php index 85afe7cde..15d6b4a5f 100644 --- a/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php +++ b/dev/tests/unit/Magento/FunctionalTestFramework/Suite/SuiteGeneratorTest.php @@ -31,7 +31,8 @@ class SuiteGeneratorTest extends MagentoTestCase { /** - * Before test functionality + * Before test functionality. + * * @return void */ protected function setUp(): void @@ -290,19 +291,27 @@ public function testGenerateSplitSuiteFromTest(): void * * @param array $testData * @param array $suiteData + * + * @return void * @throws Exception */ private function setMockTestAndSuiteParserOutput(array $testData, array $suiteData): void { $this->clearMockResolverProperties(); $mockSuiteGeneratorService = $this->createMock(SuiteGeneratorService::class); + $mockVoidReturnCallback = function () {};// phpcs:ignore + $mockSuiteGeneratorService ->method('clearPreviousSessionConfigEntries') - ->willReturn(null); + ->will($this->returnCallback($mockVoidReturnCallback)); $mockSuiteGeneratorService ->method('appendEntriesToConfig') - ->willReturn(null); + ->will($this->returnCallback($mockVoidReturnCallback)); + + $mockSuiteGeneratorService + ->method('generateRelevantGroupTests') + ->will($this->returnCallback($mockVoidReturnCallback)); $suiteGeneratorServiceProperty = new ReflectionProperty(SuiteGeneratorService::class, 'INSTANCE'); $suiteGeneratorServiceProperty->setAccessible(true); @@ -324,7 +333,6 @@ private function setMockTestAndSuiteParserOutput(array $testData, array $suiteDa ->willReturn('namespace'); $objectManager = ObjectManagerFactory::getObjectManager(); - $objectManagerMockInstance = $this->createMock(ObjectManager::class); $objectManagerMockInstance ->method('create') diff --git a/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php b/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php index 9aed81c5c..58823e195 100644 --- a/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php +++ b/src/Magento/FunctionalTestingFramework/Suite/Service/SuiteGeneratorService.php @@ -8,8 +8,10 @@ namespace Magento\FunctionalTestingFramework\Suite\Service; use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException; +use Magento\FunctionalTestingFramework\Exceptions\TestReferenceException; use Magento\FunctionalTestingFramework\Suite\SuiteGenerator; use Magento\FunctionalTestingFramework\Util\Path\FilePathFormatter; +use Magento\FunctionalTestingFramework\Util\TestGenerator; use Symfony\Component\Yaml\Yaml; /** @@ -52,7 +54,7 @@ public static function getInstance(): SuiteGeneratorService * @return void * @throws TestFrameworkException */ - public function clearPreviousSessionConfigEntries() + public function clearPreviousSessionConfigEntries(): void { $ymlArray = self::getYamlFileContents(); $newYmlArray = $ymlArray; @@ -65,7 +67,6 @@ public function clearPreviousSessionConfigEntries() unset($newYmlArray[SuiteGenerator::YAML_EXTENSIONS_TAG][SuiteGenerator::YAML_ENABLED_TAG][$key]); } } - // needed for proper yml file generation based on indices $newYmlArray[SuiteGenerator::YAML_EXTENSIONS_TAG][SuiteGenerator::YAML_ENABLED_TAG] = array_values($newYmlArray[SuiteGenerator::YAML_EXTENSIONS_TAG][SuiteGenerator::YAML_ENABLED_TAG]); @@ -74,7 +75,6 @@ public function clearPreviousSessionConfigEntries() if (array_key_exists(SuiteGenerator::YAML_GROUPS_TAG, $newYmlArray)) { unset($newYmlArray[SuiteGenerator::YAML_GROUPS_TAG]); } - $ymlText = SuiteGenerator::YAML_COPYRIGHT_TEXT . Yaml::dump($newYmlArray, 10); file_put_contents(self::getYamlConfigFilePath() . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); } @@ -91,7 +91,7 @@ public function clearPreviousSessionConfigEntries() * @return void * @throws TestFrameworkException */ - public function appendEntriesToConfig(string $suiteName, string $suitePath, ?string $groupNamespace) + public function appendEntriesToConfig(string $suiteName, string $suitePath, ?string $groupNamespace): void { $relativeSuitePath = substr($suitePath, strlen(TESTS_BP)); $relativeSuitePath = ltrim($relativeSuitePath, DIRECTORY_SEPARATOR); @@ -110,6 +110,23 @@ public function appendEntriesToConfig(string $suiteName, string $suitePath, ?str file_put_contents(self::getYamlConfigFilePath() . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME, $ymlText); } + /** + * Function which takes a string which is the desired output directory (under _generated) and an array of tests + * relevant to the suite to be generated. The function takes this information and creates a new instance of the + * test generator which is then called to create all the test files for the suite. + * + * @param string $path + * @param array $tests + * + * @return void + * @throws TestReferenceException + */ + public function generateRelevantGroupTests(string $path, array $tests): void + { + $testGenerator = TestGenerator::getInstance($path, $tests); + $testGenerator->createAllTestFiles(null, []); + } + /** * Function to return contents of codeception.yml file for config changes. * @@ -120,7 +137,6 @@ private static function getYamlFileContents(): array { $configYmlFile = self::getYamlConfigFilePath() . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME; $defaultConfigYmlFile = self::getYamlConfigFilePath() . SuiteGenerator::YAML_CODECEPTION_DIST_FILENAME; - $ymlContents = null; if (file_exists($configYmlFile)) { $ymlContents = file_get_contents($configYmlFile); @@ -137,7 +153,7 @@ private static function getYamlFileContents(): array * @return string * @throws TestFrameworkException */ - private static function getYamlConfigFilePath() + private static function getYamlConfigFilePath(): string { return FilePathFormatter::format(TESTS_BP); } diff --git a/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php b/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php index 37e370242..ced0ac552 100644 --- a/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php +++ b/src/Magento/FunctionalTestingFramework/Suite/SuiteGenerator.php @@ -346,18 +346,18 @@ private static function clearPreviousSessionConfigEntries() /** * Function which takes a string which is the desired output directory (under _generated) and an array of tests - * relevant to the suite to be generated. The function takes this information and creates a new instance of the test - * generator which is then called to create all the test files for the suite. + * relevant to the suite to be generated. The function takes this information and creates a new instance of the + * test generator which is then called to create all the test files for the suite. * * @param string $path * @param array $tests + * * @return void * @throws TestReferenceException */ private function generateRelevantGroupTests($path, $tests) { - $testGenerator = TestGenerator::getInstance($path, $tests); - $testGenerator->createAllTestFiles(null, []); + SuiteGeneratorService::getInstance()->generateRelevantGroupTests($path, $tests); } /**