Skip to content

Commit 1fddfb6

Browse files
authored
Merge pull request #251 from magento/MQE-1260
MQE-1260: Create RERUN_COUNT field in Jenkins MFTF Parameters section same as MTF parameters section
2 parents 4c8b297 + 7543050 commit 1fddfb6

File tree

2 files changed

+197
-0
lines changed

2 files changed

+197
-0
lines changed

src/Magento/FunctionalTestingFramework/Console/CommandList.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public function __construct(array $commands = [])
3535
'generate:tests' => new GenerateTestsCommand(),
3636
'run:test' => new RunTestCommand(),
3737
'run:group' => new RunTestGroupCommand(),
38+
'run:failed' => new RunTestFailedCommand(),
3839
'setup:env' => new SetupEnvCommand(),
3940
'upgrade:tests' => new UpgradeTestsCommand(),
4041
] + $commands;
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types = 1);
7+
8+
namespace Magento\FunctionalTestingFramework\Console;
9+
10+
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
11+
use Symfony\Component\Console\Input\ArrayInput;
12+
use Symfony\Component\Console\Input\InputInterface;
13+
use Symfony\Component\Console\Output\OutputInterface;
14+
use Symfony\Component\Process\Process;
15+
use Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException;
16+
17+
class RunTestFailedCommand extends BaseGenerateCommand
18+
{
19+
/**
20+
* Default Test group to signify not in suite
21+
*/
22+
const DEFAULT_TEST_GROUP = 'default';
23+
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+
const TESTS_MANIFEST_FILE= TESTS_MODULE_PATH .
34+
DIRECTORY_SEPARATOR .
35+
"_generated" .
36+
DIRECTORY_SEPARATOR .
37+
"testManifest.txt";
38+
39+
/**
40+
* @var array
41+
*/
42+
private $failedList = [];
43+
44+
/**
45+
* Configures the current command.
46+
*
47+
* @return void
48+
*/
49+
protected function configure()
50+
{
51+
$this->setName('run:failed')
52+
->setDescription('Execute a set of tests referenced via failed file');
53+
54+
parent::configure();
55+
}
56+
57+
/**
58+
* Executes the current command.
59+
*
60+
* @param InputInterface $input
61+
* @param OutputInterface $output
62+
* @return integer|null|void
63+
* @throws \Exception
64+
*
65+
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
66+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
67+
*/
68+
protected function execute(InputInterface $input, OutputInterface $output)
69+
{
70+
// Create Mftf Configuration
71+
MftfApplicationConfig::create(
72+
false,
73+
MftfApplicationConfig::GENERATION_PHASE,
74+
false,
75+
false
76+
);
77+
78+
$testConfiguration = $this->getFailedTestList();
79+
80+
if ($testConfiguration === null) {
81+
return null;
82+
}
83+
84+
$command = $this->getApplication()->find('generate:tests');
85+
$args = ['--tests' => $testConfiguration, '--remove' => true];
86+
87+
$command->run(new ArrayInput($args), $output);
88+
89+
$testManifestList = $this->readTestManifestFile();
90+
91+
foreach ($testManifestList as $testCommand) {
92+
$codeceptionCommand = realpath(PROJECT_ROOT . '/vendor/bin/codecept') . ' run functional ';
93+
$codeceptionCommand .= $testCommand;
94+
95+
$process = new Process($codeceptionCommand);
96+
$process->setWorkingDirectory(TESTS_BP);
97+
$process->setIdleTimeout(600);
98+
$process->setTimeout(0);
99+
$process->run(
100+
function ($type, $buffer) use ($output) {
101+
$output->write($buffer);
102+
}
103+
);
104+
if (file_exists(self::TESTS_FAILED_FILE)) {
105+
$this->failedList = array_merge(
106+
$this->failedList,
107+
$this->readFailedTestFile(self::TESTS_FAILED_FILE)
108+
);
109+
}
110+
}
111+
foreach ($this->failedList as $test) {
112+
$this->writeFailedTestToFile($test, self::TESTS_FAILED_FILE);
113+
}
114+
}
115+
116+
/**
117+
* Returns a json string of tests that failed on the last run
118+
*
119+
* @return string
120+
*/
121+
private function getFailedTestList()
122+
{
123+
$failedTestDetails = ['tests' => [], 'suites' => []];
124+
125+
if (realpath(self::TESTS_FAILED_FILE)) {
126+
$testList = $this->readFailedTestFile(self::TESTS_FAILED_FILE);
127+
128+
foreach ($testList as $test) {
129+
if (!empty($test)) {
130+
$this->writeFailedTestToFile($test, self::TESTS_RERUN_FILE);
131+
$testInfo = explode(DIRECTORY_SEPARATOR, $test);
132+
$testName = explode(":", $testInfo[count($testInfo) - 1])[1];
133+
$suiteName = $testInfo[count($testInfo) - 2];
134+
135+
if ($suiteName == self::DEFAULT_TEST_GROUP) {
136+
array_push($failedTestDetails['tests'], $testName);
137+
} else {
138+
$failedTestDetails['suites'] = array_merge_recursive(
139+
$failedTestDetails['suites'],
140+
[$suiteName => [$testName]]
141+
);
142+
}
143+
}
144+
}
145+
}
146+
if (empty($failedTestDetails['tests']) & empty($failedTestDetails['suites'])) {
147+
return null;
148+
}
149+
if (empty($failedTestDetails['tests'])) {
150+
$failedTestDetails['tests'] = null;
151+
}
152+
if (empty($failedTestDetails['suites'])) {
153+
$failedTestDetails['suites'] = null;
154+
}
155+
$testConfigurationJson = json_encode($failedTestDetails);
156+
return $testConfigurationJson;
157+
}
158+
159+
/**
160+
* Returns an array of run commands read from the manifest file created post generation
161+
*
162+
* @return array|boolean
163+
*/
164+
private function readTestManifestFile()
165+
{
166+
return file(self::TESTS_MANIFEST_FILE, FILE_IGNORE_NEW_LINES);
167+
}
168+
169+
/**
170+
* Returns an array of tests read from the failed test file in _output
171+
*
172+
* @param string $filePath
173+
* @return array|boolean
174+
*/
175+
private function readFailedTestFile($filePath)
176+
{
177+
return file($filePath, FILE_IGNORE_NEW_LINES);
178+
}
179+
180+
/**
181+
* Writes the test name to a file if it does not already exist
182+
*
183+
* @param string $test
184+
* @return void
185+
*/
186+
private function writeFailedTestToFile($test, $filePath)
187+
{
188+
if (file_exists($filePath)) {
189+
if (strpos(file_get_contents($filePath), $test) === false) {
190+
file_put_contents($filePath, "\n" . $test, FILE_APPEND);
191+
}
192+
} else {
193+
file_put_contents($filePath, $test . "\n");
194+
}
195+
}
196+
}

0 commit comments

Comments
 (0)