SuiteGenerationTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace tests\verification\Tests;
  7. use Magento\FunctionalTestingFramework\Suite\SuiteGenerator;
  8. use Magento\FunctionalTestingFramework\Util\Filesystem\DirSetupUtil;
  9. use Magento\FunctionalTestingFramework\Util\Manifest\DefaultTestManifest;
  10. use Magento\FunctionalTestingFramework\Util\Manifest\ParallelTestManifest;
  11. use Magento\FunctionalTestingFramework\Util\Manifest\TestManifestFactory;
  12. use PHPUnit\Util\Filesystem;
  13. use Symfony\Component\Yaml\Yaml;
  14. use tests\unit\Util\TestLoggingUtil;
  15. use tests\util\MftfTestCase;
  16. class SuiteGenerationTest extends MftfTestCase
  17. {
  18. const RESOURCES_DIR = TESTS_BP . DIRECTORY_SEPARATOR . 'verification' . DIRECTORY_SEPARATOR . 'Resources';
  19. const CONFIG_YML_FILE = TESTS_BP . DIRECTORY_SEPARATOR . SuiteGenerator::YAML_CODECEPTION_CONFIG_FILENAME;
  20. const GENERATE_RESULT_DIR = TESTS_BP .
  21. DIRECTORY_SEPARATOR .
  22. "verification" .
  23. DIRECTORY_SEPARATOR .
  24. "_generated" .
  25. DIRECTORY_SEPARATOR;
  26. /**
  27. * Array which stores state of any existing config.yml groups
  28. *
  29. * @var array
  30. */
  31. private static $TEST_GROUPS = [];
  32. /**
  33. * Set up config.yml for testing
  34. */
  35. public static function setUpBeforeClass()
  36. {
  37. // destroy _generated if it exists
  38. if (file_exists(self::GENERATE_RESULT_DIR)) {
  39. DirSetupUtil::rmdirRecursive(self::GENERATE_RESULT_DIR);
  40. }
  41. }
  42. public function setUp()
  43. {
  44. // copy config yml file to test dir
  45. $fileSystem = new \Symfony\Component\Filesystem\Filesystem();
  46. $fileSystem->copy(
  47. realpath(
  48. FW_BP
  49. . DIRECTORY_SEPARATOR
  50. . 'etc'
  51. . DIRECTORY_SEPARATOR
  52. . 'config'
  53. . DIRECTORY_SEPARATOR
  54. . 'codeception.dist.yml'
  55. ),
  56. self::CONFIG_YML_FILE
  57. );
  58. TestLoggingUtil::getInstance()->setMockLoggingUtil();
  59. }
  60. /**
  61. * Test basic generation of a suite
  62. */
  63. public function testSuiteGeneration1()
  64. {
  65. $groupName = 'functionalSuite1';
  66. $expectedContents = [
  67. 'additionalTestCest.php',
  68. 'additionalIncludeTest2Cest.php',
  69. 'IncludeTest2Cest.php',
  70. 'IncludeTestCest.php'
  71. ];
  72. // Generate the Suite
  73. SuiteGenerator::getInstance()->generateSuite($groupName);
  74. // Validate log message and add group name for later deletion
  75. TestLoggingUtil::getInstance()->validateMockLogStatement(
  76. 'info',
  77. "suite generated",
  78. ['suite' => $groupName, 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . $groupName]
  79. );
  80. self::$TEST_GROUPS[] = $groupName;
  81. // Validate Yaml file updated
  82. $yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
  83. $this->assertArrayHasKey($groupName, $yml['groups']);
  84. $suiteResultBaseDir = self::GENERATE_RESULT_DIR .
  85. DIRECTORY_SEPARATOR .
  86. $groupName .
  87. DIRECTORY_SEPARATOR;
  88. // Validate tests have been generated
  89. $dirContents = array_diff(scandir($suiteResultBaseDir), ['..', '.']);
  90. foreach ($expectedContents as $expectedFile) {
  91. $this->assertTrue(in_array($expectedFile, $dirContents));
  92. }
  93. }
  94. /**
  95. * Test generation of parallel suite groups
  96. */
  97. public function testSuiteGenerationParallel()
  98. {
  99. $groupName = 'functionalSuite1';
  100. $expectedGroups = [
  101. 'functionalSuite1_0',
  102. 'functionalSuite1_1',
  103. 'functionalSuite1_2',
  104. 'functionalSuite1_3'
  105. ];
  106. $expectedContents = [
  107. 'additionalTestCest.php',
  108. 'additionalIncludeTest2Cest.php',
  109. 'IncludeTest2Cest.php',
  110. 'IncludeTestCest.php'
  111. ];
  112. //createParallelManifest
  113. /** @var ParallelTestManifest $parallelManifest */
  114. $parallelManifest = TestManifestFactory::makeManifest("parallel", ["functionalSuite1" => []]);
  115. // Generate the Suite
  116. $parallelManifest->createTestGroups(1);
  117. SuiteGenerator::getInstance()->generateAllSuites($parallelManifest);
  118. // Validate log message (for final group) and add group name for later deletion
  119. $expectedGroup = $expectedGroups[count($expectedGroups)-1] ;
  120. TestLoggingUtil::getInstance()->validateMockLogStatement(
  121. 'info',
  122. "suite generated",
  123. ['suite' => $expectedGroup, 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . $expectedGroup]
  124. );
  125. self::$TEST_GROUPS[] = $groupName;
  126. // Validate Yaml file updated
  127. $yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
  128. $this->assertEquals(array_intersect($expectedGroups, array_keys($yml['groups'])), $expectedGroups);
  129. foreach ($expectedGroups as $expectedFolder) {
  130. $suiteResultBaseDir = self::GENERATE_RESULT_DIR .
  131. DIRECTORY_SEPARATOR .
  132. $expectedFolder .
  133. DIRECTORY_SEPARATOR;
  134. // Validate tests have been generated
  135. $dirContents = array_diff(scandir($suiteResultBaseDir), ['..', '.']);
  136. //Validate only one test has been added to each group since lines are set to 1
  137. $this->assertEquals(1, count($dirContents));
  138. $this->assertContains(array_values($dirContents)[0], $expectedContents);
  139. }
  140. }
  141. /**
  142. * Test hook groups generated during suite generation
  143. */
  144. public function testSuiteGenerationHooks()
  145. {
  146. $groupName = 'functionalSuiteHooks';
  147. $expectedContents = [
  148. 'IncludeTestCest.php'
  149. ];
  150. // Generate the Suite
  151. SuiteGenerator::getInstance()->generateSuite($groupName);
  152. // Validate log message and add group name for later deletion
  153. TestLoggingUtil::getInstance()->validateMockLogStatement(
  154. 'info',
  155. "suite generated",
  156. ['suite' => $groupName, 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . $groupName]
  157. );
  158. self::$TEST_GROUPS[] = $groupName;
  159. // Validate Yaml file updated
  160. $yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
  161. $this->assertArrayHasKey($groupName, $yml['groups']);
  162. $suiteResultBaseDir = self::GENERATE_RESULT_DIR .
  163. DIRECTORY_SEPARATOR .
  164. $groupName .
  165. DIRECTORY_SEPARATOR;
  166. // Validate tests have been generated
  167. $dirContents = array_diff(scandir($suiteResultBaseDir), ['..', '.']);
  168. foreach ($expectedContents as $expectedFile) {
  169. $this->assertTrue(in_array($expectedFile, $dirContents));
  170. }
  171. //assert group file created and contains correct contents
  172. $groupFile = PROJECT_ROOT .
  173. DIRECTORY_SEPARATOR .
  174. "src" .
  175. DIRECTORY_SEPARATOR .
  176. "Magento" .
  177. DIRECTORY_SEPARATOR .
  178. "FunctionalTestingFramework" .
  179. DIRECTORY_SEPARATOR .
  180. "Group" .
  181. DIRECTORY_SEPARATOR .
  182. $groupName .
  183. ".php";
  184. $this->assertTrue(file_exists($groupFile));
  185. $this->assertFileEquals(
  186. self::RESOURCES_PATH . DIRECTORY_SEPARATOR . $groupName . ".txt",
  187. $groupFile
  188. );
  189. }
  190. /**
  191. * Test generation of parallel suite groups
  192. */
  193. public function testSuiteGenerationSingleRun()
  194. {
  195. //using functionalSuite2 to avoid directory caching
  196. $groupName = 'functionalSuite2';
  197. $expectedContents = [
  198. 'additionalTestCest.php',
  199. 'additionalIncludeTest2Cest.php',
  200. 'IncludeTest2Cest.php',
  201. 'IncludeTestCest.php'
  202. ];
  203. //createParallelManifest
  204. /** @var DefaultTestManifest $parallelManifest */
  205. $singleRunManifest = TestManifestFactory::makeManifest("singleRun", ["functionalSuite2" => []]);
  206. // Generate the Suite
  207. SuiteGenerator::getInstance()->generateAllSuites($singleRunManifest);
  208. $singleRunManifest->generate();
  209. // Validate log message and add group name for later deletion
  210. TestLoggingUtil::getInstance()->validateMockLogStatement(
  211. 'info',
  212. "suite generated",
  213. ['suite' => $groupName, 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . $groupName]
  214. );
  215. self::$TEST_GROUPS[] = $groupName;
  216. // Validate Yaml file updated
  217. $yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
  218. $this->assertArrayHasKey($groupName, $yml['groups']);
  219. $suiteResultBaseDir = self::GENERATE_RESULT_DIR .
  220. DIRECTORY_SEPARATOR .
  221. $groupName .
  222. DIRECTORY_SEPARATOR;
  223. // Validate tests have been generated
  224. $dirContents = array_diff(scandir($suiteResultBaseDir), ['..', '.']);
  225. foreach ($expectedContents as $expectedFile) {
  226. $this->assertTrue(in_array($expectedFile, $dirContents));
  227. }
  228. $expectedManifest = "verification"
  229. . DIRECTORY_SEPARATOR
  230. . "_generated"
  231. . DIRECTORY_SEPARATOR
  232. . "default"
  233. . DIRECTORY_SEPARATOR
  234. . PHP_EOL
  235. . "-g functionalSuite2"
  236. . PHP_EOL;
  237. $this->assertEquals($expectedManifest, file_get_contents(self::getManifestFilePath()));
  238. }
  239. /**
  240. * Test extends tests generation in a suite
  241. */
  242. public function testSuiteGenerationWithExtends()
  243. {
  244. $groupName = 'suiteExtends';
  245. $expectedFileNames = [
  246. 'ExtendedChildTestInSuiteCest'
  247. ];
  248. // Generate the Suite
  249. SuiteGenerator::getInstance()->generateSuite($groupName);
  250. // Validate log message and add group name for later deletion
  251. TestLoggingUtil::getInstance()->validateMockLogStatement(
  252. 'info',
  253. "suite generated",
  254. ['suite' => $groupName, 'relative_path' => "_generated" . DIRECTORY_SEPARATOR . $groupName]
  255. );
  256. self::$TEST_GROUPS[] = $groupName;
  257. // Validate Yaml file updated
  258. $yml = Yaml::parse(file_get_contents(self::CONFIG_YML_FILE));
  259. $this->assertArrayHasKey($groupName, $yml['groups']);
  260. $suiteResultBaseDir = self::GENERATE_RESULT_DIR .
  261. $groupName .
  262. DIRECTORY_SEPARATOR;
  263. // Validate tests have been generated
  264. $dirContents = array_diff(scandir($suiteResultBaseDir), ['..', '.']);
  265. foreach ($expectedFileNames as $expectedFileName) {
  266. $this->assertTrue(in_array($expectedFileName . ".php", $dirContents));
  267. $this->assertFileEquals(
  268. self::RESOURCES_PATH . DIRECTORY_SEPARATOR . $expectedFileName . ".txt",
  269. $suiteResultBaseDir . $expectedFileName . ".php"
  270. );
  271. }
  272. }
  273. /**
  274. * revert any changes made to config.yml
  275. * remove _generated directory
  276. */
  277. public function tearDown()
  278. {
  279. DirSetupUtil::rmdirRecursive(self::GENERATE_RESULT_DIR);
  280. // delete config yml file from test dir
  281. $fileSystem = new \Symfony\Component\Filesystem\Filesystem();
  282. $fileSystem->remove(
  283. self::CONFIG_YML_FILE
  284. );
  285. }
  286. /**
  287. * Remove yml if created during tests and did not exist before
  288. */
  289. public static function tearDownAfterClass()
  290. {
  291. TestLoggingUtil::getInstance()->clearMockLoggingUtil();
  292. }
  293. /**
  294. * Getter for manifest file path
  295. *
  296. * @return string
  297. */
  298. private static function getManifestFilePath()
  299. {
  300. return TESTS_BP .
  301. DIRECTORY_SEPARATOR .
  302. "verification" .
  303. DIRECTORY_SEPARATOR .
  304. "_generated" .
  305. DIRECTORY_SEPARATOR .
  306. 'testManifest.txt';
  307. }
  308. }