Skip to content

Commit e2ac7e4

Browse files
committed
MQE-2272: run:failed only runs last failed test when multiple tests are run with run:test
1 parent 9da15a8 commit e2ac7e4

File tree

4 files changed

+135
-13
lines changed

4 files changed

+135
-13
lines changed

src/Magento/FunctionalTestingFramework/Console/BaseGenerateCommand.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class BaseGenerateCommand extends Command
3636
const CODECEPT_RUN = 'codecept:run';
3737
const CODECEPT_RUN_FUNCTIONAL = self::CODECEPT_RUN . ' functional ';
3838
const CODECEPT_RUN_OPTION_NO_EXIT = ' --no-exit ';
39+
const FAILED_FILE = 'failed';
40+
const FAILED_ALL_FILE = 'failed_all';
3941

4042
/**
4143
* Enable pause()
@@ -44,13 +46,34 @@ class BaseGenerateCommand extends Command
4446
*/
4547
private $enablePause = null;
4648

49+
/**
50+
* Full path to '_output' dir
51+
*
52+
* @var string
53+
*/
54+
private $testsOutputDir = null;
55+
56+
/**
57+
* File handle for 'failed_all' file
58+
*
59+
* @var resource
60+
*/
61+
private $fhFailedAll;
62+
4763
/**
4864
* Console output style
4965
*
5066
* @var SymfonyStyle
5167
*/
5268
protected $ioStyle = null;
5369

70+
/**
71+
* Full path to 'failed' file
72+
*
73+
* @var string
74+
*/
75+
protected $testsFailedFile = null;
76+
5477
/**
5578
* Configures the base command.
5679
*
@@ -270,4 +293,93 @@ protected function codeceptRunTest(string $commandStr, OutputInterface $output)
270293
$command = $this->getApplication()->find(self::CODECEPT_RUN);
271294
return $command->run($input, $output);
272295
}
296+
297+
/**
298+
* Return tests _output directory
299+
*
300+
* @return string
301+
* @throws TestFrameworkException
302+
*/
303+
protected function getTestsOutputDir()
304+
{
305+
if (!$this->testsOutputDir) {
306+
$this->testsOutputDir = FilePathFormatter::format(TESTS_BP) .
307+
"tests" .
308+
DIRECTORY_SEPARATOR .
309+
"_output" .
310+
DIRECTORY_SEPARATOR;
311+
}
312+
313+
return $this->testsOutputDir;
314+
}
315+
316+
/**
317+
* Initialize 'failed_all' file
318+
*
319+
* @return void
320+
* @throws TestFrameworkException
321+
*/
322+
protected function initializeFailedAllFile()
323+
{
324+
// Initialize 'failed_all' file
325+
$allFailedFile = $this->getTestsOutputDir() . self::FAILED_ALL_FILE;
326+
$this->fhFailedAll = fopen($allFailedFile, 'w+');
327+
}
328+
329+
/**
330+
* Appends content of file 'failed' to file 'failed_all'
331+
*
332+
* @return void
333+
*/
334+
protected function appendRunFailed()
335+
{
336+
try {
337+
if (!$this->testsFailedFile) {
338+
$this->testsFailedFile = $this->getTestsOutputDir() . self::FAILED_FILE;
339+
}
340+
341+
if (file_exists($this->testsFailedFile)) {
342+
// Append 'failed' into 'failed_all'
343+
$contents = file_get_contents($this->testsFailedFile);
344+
if ($contents !== false && !empty($contents)) {
345+
fwrite($this->fhFailedAll, trim($contents) . PHP_EOL);
346+
}
347+
}
348+
} catch (TestFrameworkException $e) {
349+
}
350+
}
351+
352+
/**
353+
* Replace content of file 'failed' with content in file 'failed_all'
354+
*
355+
* @return void
356+
*/
357+
protected function updateRunFailedWithFailedAll()
358+
{
359+
try {
360+
if (!$this->testsFailedFile) {
361+
$this->testsFailedFile = $this->getTestsOutputDir() . self::FAILED_FILE;
362+
}
363+
364+
if (file_exists($this->getTestsOutputDir() . self::FAILED_ALL_FILE)) {
365+
// Update 'failed' with content from 'failed_all'
366+
$contents = file_get_contents($this->getTestsOutputDir() . self::FAILED_ALL_FILE);
367+
if ($contents !== false && !empty($contents)) {
368+
if (file_exists($this->testsFailedFile)) {
369+
rename($this->testsFailedFile, $this->testsFailedFile . '.copy');
370+
}
371+
if (file_put_contents($this->testsFailedFile, $contents) === false
372+
&& file_exists($this->testsFailedFile . '.copy')) {
373+
rename($this->testsFailedFile . '.copy', $this->testsFailedFile);
374+
}
375+
if (file_exists($this->testsFailedFile . '.copy')) {
376+
unlink($this->testsFailedFile . '.copy');
377+
}
378+
}
379+
fclose($this->fhFailedAll);
380+
unlink($this->getTestsOutputDir() . self::FAILED_ALL_FILE);
381+
}
382+
} catch (TestFrameworkException $e) {
383+
}
384+
}
273385
}

src/Magento/FunctionalTestingFramework/Console/RunTestCommand.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
109109

110110
$testConfigArray = json_decode($testConfiguration, true);
111111

112+
// Initialize `failed_all` file
113+
$this->initializeFailedAllFile();
114+
112115
if (isset($testConfigArray['tests'])) {
113116
$this->runTests($testConfigArray['tests'], $output);
114117
}
@@ -117,6 +120,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
117120
$this->runTestsInSuite($testConfigArray['suites'], $output);
118121
}
119122

123+
// Update `failed` with contents from `failed_all`
124+
$this->updateRunFailedWithFailedAll();
125+
120126
return max($this->returnCode, $generationErrorCode);
121127
}
122128

@@ -161,6 +167,9 @@ private function runTests(array $tests, OutputInterface $output)
161167
$fullCommand = $codeceptionCommand . $testsDirectory . $testName . ' --verbose --steps';
162168
$this->returnCode = max($this->returnCode, $this->executeTestCommand($fullCommand, $output));
163169
}
170+
171+
// Append `failed` to `failed_all`
172+
$this->appendRunFailed();
164173
}
165174
}
166175

@@ -196,6 +205,9 @@ private function runTestsInSuite(array $suitesConfig, OutputInterface $output)
196205
} else {
197206
$this->returnCode = max($this->returnCode, $this->executeTestCommand($fullCommand, $output));
198207
}
208+
209+
// Append `failed` to `failed_all`
210+
$this->appendRunFailed();
199211
}
200212
}
201213

src/Magento/FunctionalTestingFramework/Console/RunTestFailedCommand.php

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ class RunTestFailedCommand extends BaseGenerateCommand
2323
*/
2424
const DEFAULT_TEST_GROUP = 'default';
2525

26-
/**
27-
* @var string
28-
*/
29-
private $testsFailedFile;
30-
3126
/**
3227
* @var string
3328
*/
@@ -69,14 +64,8 @@ protected function configure()
6964
*/
7065
protected function execute(InputInterface $input, OutputInterface $output): int
7166
{
72-
$testsOutputDir = FilePathFormatter::format(TESTS_BP) .
73-
"tests" .
74-
DIRECTORY_SEPARATOR .
75-
"_output" .
76-
DIRECTORY_SEPARATOR;
77-
78-
$this->testsFailedFile = $testsOutputDir . "failed";
79-
$this->testsReRunFile = $testsOutputDir . "rerun_tests";
67+
$this->testsFailedFile = $this->getTestsOutputDir() . self::FAILED_FILE;
68+
$this->testsReRunFile = $this->getTestsOutputDir() . "rerun_tests";
8069
$this->testsManifestFile= FilePathFormatter::format(TESTS_MODULE_PATH) .
8170
"_generated" .
8271
DIRECTORY_SEPARATOR .

src/Magento/FunctionalTestingFramework/Console/RunTestGroupCommand.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
103103
}
104104
}
105105

106+
// Initialize `failed_all` file
107+
$this->initializeFailedAllFile();
108+
106109
if ($this->pauseEnabled()) {
107110
$commandString = self::CODECEPT_RUN_FUNCTIONAL . '--verbose --steps --debug';
108111
} else {
@@ -130,8 +133,14 @@ function ($type, $buffer) use ($output) {
130133
}
131134
);
132135
}
136+
137+
// Append `failed` to `failed_all`
138+
$this->appendRunFailed();
133139
}
134140

141+
// Update `failed` with contents from `failed_all`
142+
$this->updateRunFailedWithFailedAll();
143+
135144
foreach ($returnCodes as $returnCode) {
136145
if ($returnCode != 0) {
137146
return $returnCode;

0 commit comments

Comments
 (0)