77
88namespace Magento \FunctionalTestingFramework \Console ;
99
10- use Magento \FunctionalTestingFramework \Suite \Handlers \SuiteObjectHandler ;
1110use Magento \FunctionalTestingFramework \Config \MftfApplicationConfig ;
12- use Magento \FunctionalTestingFramework \Test \Handlers \TestObjectHandler ;
1311use Symfony \Component \Console \Input \ArrayInput ;
14- use Symfony \Component \Console \Input \InputArgument ;
1512use Symfony \Component \Console \Input \InputInterface ;
16- use Symfony \Component \Console \Input \InputOption ;
1713use Symfony \Component \Console \Output \OutputInterface ;
1814use Symfony \Component \Process \Process ;
1915use Magento \FunctionalTestingFramework \Exceptions \TestFrameworkException ;
2016
2117class RunTestFailedCommand extends BaseGenerateCommand
2218{
19+ /**
20+ * Default Test group to signify not in suite
21+ */
2322 const DEFAULT_TEST_GROUP = 'default ' ;
2423
24+ const TESTS_OUTPUT_DIR = TESTS_BP .
25+ DIRECTORY_SEPARATOR .
26+ "tests " .
27+ DIRECTORY_SEPARATOR .
28+ "_output " .
29+ DIRECTORY_SEPARATOR ;
30+
31+ const TESTS_FAILED_FILE = self ::TESTS_OUTPUT_DIR . "failed " ;
32+ const TESTS_RERUN_FILE = self ::TESTS_OUTPUT_DIR . "rerun_tests " ;
33+
2534 /**
2635 * Configures the current command.
2736 *
@@ -30,18 +39,7 @@ class RunTestFailedCommand extends BaseGenerateCommand
3039 protected function configure ()
3140 {
3241 $ this ->setName ('run:failed ' )
33- ->setDescription ('Execute a set of tests referenced via group annotations ' )
34- ->addOption (
35- 'skip-generate ' ,
36- 'k ' ,
37- InputOption::VALUE_NONE ,
38- "only execute a group of tests without generating from source xml "
39- )->addOption (
40- "force " ,
41- 'f ' ,
42- InputOption::VALUE_NONE ,
43- 'force generation of tests regardless of Magento Instance Configuration '
44- );
42+ ->setDescription ('Execute a set of tests referenced via failed file ' );
4543
4644 parent ::configure ();
4745 }
@@ -55,41 +53,29 @@ protected function configure()
5553 * @throws \Exception
5654 *
5755 * @SuppressWarnings(PHPMD.UnusedLocalVariable)
56+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
5857 */
5958 protected function execute (InputInterface $ input , OutputInterface $ output )
6059 {
61- $ skipGeneration = $ input ->getOption ('skip-generate ' );
62- $ force = $ input ->getOption ('force ' );
63- // $groups = $input->getArgument('groups');
64- $ remove = $ input ->getOption ('remove ' );
65-
66- if ($ skipGeneration and $ remove ) {
67- // "skip-generate" and "remove" options cannot be used at the same time
68- throw new TestFrameworkException (
69- "\"skip-generate \" and \"remove \" options can not be used at the same time. "
70- );
71- }
72-
7360 // Create Mftf Configuration
7461 MftfApplicationConfig::create (
75- $ force ,
62+ false ,
7663 MftfApplicationConfig::GENERATION_PHASE ,
7764 false ,
7865 false
7966 );
8067
81- if (!$ skipGeneration ) {
82- $ testConfiguration = $ this ->getFailedTestList ();
83- $ command = $ this ->getApplication ()->find ('generate:tests ' );
84- $ args = [
85- '--tests ' => $ testConfiguration ,
86- '--force ' => $ force ,
87- '--remove ' => $ remove
88- ];
68+ $ testConfiguration = $ this ->getFailedTestList ();
8969
90- $ command ->run (new ArrayInput ($ args ), $ output );
70+ if ($ testConfiguration === null ) {
71+ return null ;
9172 }
9273
74+ $ command = $ this ->getApplication ()->find ('generate:tests ' );
75+ $ args = ['--tests ' => $ testConfiguration , '--remove ' => true ];
76+
77+ $ command ->run (new ArrayInput ($ args ), $ output );
78+
9379 $ codeceptionCommand = realpath (PROJECT_ROOT . '/vendor/bin/codecept ' ) . ' run functional --verbose --steps ' ;
9480
9581 $ process = new Process ($ codeceptionCommand );
@@ -106,7 +92,7 @@ function ($type, $buffer) use ($output) {
10692 /**
10793 * Returns a json string of tests that failed on the last run
10894 *
109- * @return string[]
95+ * @return string
11096 */
11197 private function getFailedTestList ()
11298 {
@@ -121,10 +107,10 @@ private function getFailedTestList()
121107 $ failedTestDetails = ['tests ' => [], 'suites ' => []];
122108
123109 if (realpath ($ failedTestPath )) {
124-
125- $ testList = file ($ failedTestPath ,FILE_IGNORE_NEW_LINES );
110+ $ testList = $ this ->readFailedTestFile ($ failedTestPath );
126111
127112 foreach ($ testList as $ test ) {
113+ $ this ->writeFailedTestToFile ($ test );
128114 $ testInfo = explode (DIRECTORY_SEPARATOR , $ test );
129115 $ testName = explode (": " , $ testInfo [count ($ testInfo ) - 1 ])[1 ];
130116 $ suiteName = $ testInfo [count ($ testInfo ) - 2 ];
@@ -139,7 +125,44 @@ private function getFailedTestList()
139125 }
140126 }
141127 }
128+ if (empty ($ failedTestDetails ['tests ' ]) & empty ($ failedTestDetails ['suites ' ])) {
129+ return null ;
130+ }
131+ if (empty ($ failedTestDetails ['tests ' ])) {
132+ $ failedTestDetails ['tests ' ] = null ;
133+ }
134+ if (empty ($ failedTestDetails ['suites ' ])) {
135+ $ failedTestDetails ['suites ' ] = null ;
136+ }
142137 $ testConfigurationJson = json_encode ($ failedTestDetails );
143138 return $ testConfigurationJson ;
144139 }
140+
141+ /**
142+ * Returns an array of tests read from the failed test file in _output
143+ *
144+ * @param string $filePath
145+ * @return array|boolean
146+ */
147+ private function readFailedTestFile ($ filePath )
148+ {
149+ return file ($ filePath , FILE_IGNORE_NEW_LINES );
150+ }
151+
152+ /**
153+ * Writes the test name to a file if it does not already exist
154+ *
155+ * @param string $test
156+ * @return void
157+ */
158+ private function writeFailedTestToFile ($ test )
159+ {
160+ if (realpath (self ::TESTS_RERUN_FILE )) {
161+ if (strpos (file_get_contents (self ::TESTS_RERUN_FILE ), $ test ) == false ) {
162+ file_put_contents (self ::TESTS_RERUN_FILE , $ test . "\n" , FILE_APPEND );
163+ }
164+ } else {
165+ file_put_contents (self ::TESTS_RERUN_FILE , $ test . "\n" );
166+ }
167+ }
145168}
0 commit comments