Skip to content

Commit 48b9318

Browse files
authored
Merge pull request #2443 from magento-pangolin/MQE-975
[Pangolin] Deliver changes related to MFTF 2.2.0 release
2 parents d8de08f + 959dfac commit 48b9318

File tree

59 files changed

+678
-620
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+678
-620
lines changed

dev/tests/acceptance/RoboFile.php

Lines changed: 163 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* See COPYING.txt for license details.
55
*/
66

7+
use Symfony\Component\Yaml\Yaml;
8+
79
/** This is project's console commands configuration for Robo task runner.
810
*
911
* @codingStandardsIgnoreStart
@@ -13,6 +15,12 @@ class RoboFile extends \Robo\Tasks
1315
{
1416
use Robo\Task\Base\loadShortcuts;
1517

18+
public function __construct()
19+
{
20+
require 'tests'. DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR . '_bootstrap.php';
21+
define('VENDOR_BIN_PATH', PROJECT_ROOT . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR);
22+
23+
}
1624
/**
1725
* Duplicate the Example configuration files used to customize the Project for customization.
1826
*
@@ -25,6 +33,66 @@ function cloneFiles()
2533
$this->_exec('cp -vf tests'. DIRECTORY_SEPARATOR .'functional.suite.dist.yml tests'. DIRECTORY_SEPARATOR .'functional.suite.yml');
2634
}
2735

36+
/**
37+
* Finds relative paths between codeception.yml file and MFTF path, and overwrites the default paths.
38+
*
39+
* @return void
40+
*/
41+
private function buildCodeceptionPaths()
42+
{
43+
$relativePathFunc = function ($from, $to)
44+
{
45+
$from = is_dir($from) ? rtrim($from, '\/') . '/' : $from;
46+
$to = is_dir($to) ? rtrim($to, '\/') . '/' : $to;
47+
$from = str_replace('\\', '/', $from);
48+
$to = str_replace('\\', '/', $to);
49+
50+
$from = explode('/', $from);
51+
$to = explode('/', $to);
52+
$relPath = $to;
53+
54+
foreach($from as $depth => $dir) {
55+
// find first non-matching dir
56+
if($dir === $to[$depth]) {
57+
// ignore this directory
58+
array_shift($relPath);
59+
} else {
60+
// get number of remaining dirs to $from
61+
$remaining = count($from) - $depth;
62+
if($remaining > 1) {
63+
// add traversals up to first matching dir
64+
$padLength = (count($relPath) + $remaining - 1) * -1;
65+
$relPath = array_pad($relPath, $padLength, '..');
66+
break;
67+
} else {
68+
$relPath[0] = './' . $relPath[0];
69+
}
70+
}
71+
}
72+
return implode('/', $relPath);
73+
};
74+
75+
//Find travel path from codeception.yml to FW_BP
76+
$configYmlPath = dirname(dirname(TESTS_BP)) . DIRECTORY_SEPARATOR;
77+
$relativePath = call_user_func($relativePathFunc, $configYmlPath, FW_BP);
78+
$configYmlFile = $configYmlPath . "codeception.yml";
79+
$defaultConfigYmlFile = $configYmlPath . "codeception.dist.yml";
80+
81+
if (file_exists($configYmlFile)) {
82+
$ymlContents = file_get_contents($configYmlFile);
83+
} else {
84+
$ymlContents = file_get_contents($defaultConfigYmlFile);
85+
}
86+
$ymlArray = Yaml::parse($ymlContents) ?? [];
87+
if (!array_key_exists("paths", $ymlArray)) {
88+
$ymlArray["paths"] = [];
89+
}
90+
$ymlArray["paths"]["support"] = $relativePath . 'src/Magento/FunctionalTestingFramework';
91+
$ymlArray["paths"]["envs"] = $relativePath . 'etc/_envs';
92+
$ymlText = Yaml::dump($ymlArray, 10);
93+
file_put_contents($configYmlFile, $ymlText);
94+
}
95+
2896
/**
2997
* Duplicate the Example configuration files for the Project.
3098
* Build the Codeception project.
@@ -34,29 +102,110 @@ function cloneFiles()
34102
function buildProject()
35103
{
36104
$this->cloneFiles();
37-
$this->_exec('vendor'. DIRECTORY_SEPARATOR .'bin'. DIRECTORY_SEPARATOR .'codecept build');
105+
$this->buildCodeceptionPaths();
106+
$this->_exec(VENDOR_BIN_PATH .'codecept build');
38107
}
39108

40109
/**
41-
* Generate all Tests in PHP.
110+
* Generate all Tests in PHP OR Generate set of tests via passing array of tests
42111
*
112+
* @param array $tests
43113
* @param array $opts
44114
* @return void
45115
*/
46-
function generateTests($opts = ['config' => null, 'force' => false, 'nodes' => null])
116+
function generateTests(array $tests, $opts = [
117+
'config' => null,
118+
'force' => false,
119+
'nodes' => null,
120+
'lines' => 500,
121+
'tests' => null
122+
])
47123
{
48-
$GLOBALS['GENERATE_TESTS'] = true;
124+
require 'tests'. DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR . '_bootstrap.php';
125+
$testConfiguration = $this->createTestConfiguration($tests, $opts);
49126

50-
if ($opts['force'])
51-
{
52-
$GLOBALS['FORCE_PHP_GENERATE'] = true;
127+
// maintain backwards compatability for devops by not removing the nodes option yet
128+
$lines = $opts['lines'];
129+
130+
// create our manifest file here
131+
$testManifest = \Magento\FunctionalTestingFramework\Util\Manifest\TestManifestFactory::makeManifest($opts['config'],$testConfiguration['suites']);
132+
\Magento\FunctionalTestingFramework\Util\TestGenerator::getInstance(null, $testConfiguration['tests'])->createAllTestFiles($testManifest);
133+
134+
if ($opts['config'] == 'parallel') {
135+
$testManifest->createTestGroups($lines);
53136
}
54137

55-
require 'tests'. DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR . '_bootstrap.php';
56-
\Magento\FunctionalTestingFramework\Util\TestGenerator::getInstance()->createAllTestFiles($opts['config'], $opts['nodes']);
138+
\Magento\FunctionalTestingFramework\Suite\SuiteGenerator::getInstance()->generateAllSuites($testManifest);
139+
$testManifest->generate();
140+
57141
$this->say("Generate Tests Command Run");
58142
}
59143

144+
145+
/**
146+
* Function which builds up a configuration including test and suites for consumption of Magento generation methods.
147+
*
148+
* @param array $tests
149+
* @param array $opts
150+
* @return array
151+
*/
152+
private function createTestConfiguration($tests, $opts)
153+
{
154+
// set our application configuration so we can references the user options in our framework
155+
Magento\FunctionalTestingFramework\Config\MftfApplicationConfig::create(
156+
$opts['force'],
157+
Magento\FunctionalTestingFramework\Config\MftfApplicationConfig::GENERATION_PHASE,
158+
$opts['verbose']
159+
);
160+
161+
$testConfiguration = [];
162+
$testConfiguration['tests'] = $tests;
163+
$testConfiguration['suites'] = [];
164+
165+
$testConfiguration = $this->parseTestsConfigJson($opts['tests'], $testConfiguration);
166+
167+
// if we have references to specific tests, we resolve the test objects and pass them to the config
168+
if (!empty($testConfiguration['tests']))
169+
{
170+
$testObjects = [];
171+
172+
foreach ($testConfiguration['tests'] as $test)
173+
{
174+
$testObjects[$test] = Magento\FunctionalTestingFramework\Test\Handlers\TestObjectHandler::getInstance()->getObject($test);
175+
}
176+
177+
$testConfiguration['tests'] = $testObjects;
178+
}
179+
180+
return $testConfiguration;
181+
}
182+
183+
/**
184+
* Function which takes a json string of potential custom configuration and parses/validates the resulting json
185+
* passed in by the user. The result is a testConfiguration array.
186+
*
187+
* @param string $json
188+
* @param array $testConfiguration
189+
* @return array
190+
*/
191+
private function parseTestsConfigJson($json, $testConfiguration) {
192+
if ($json == null) {
193+
return $testConfiguration;
194+
}
195+
196+
$jsonTestConfiguration = [];
197+
$testConfigArray = json_decode($json, true);
198+
199+
// stop execution if we have failed to properly parse any json
200+
if (json_last_error() != JSON_ERROR_NONE) {
201+
throw new \Magento\FunctionalTestingFramework\Exceptions\TestFrameworkException("JSON could not be parsed: " . json_last_error_msg());
202+
}
203+
204+
$jsonTestConfiguration['tests'] = $testConfigArray['tests'] ?? null;;
205+
$jsonTestConfiguration['suites'] = $testConfigArray['suites'] ?? null;
206+
return $jsonTestConfiguration;
207+
}
208+
60209
/**
61210
* Generate a suite based on name(s) passed in as args.
62211
*
@@ -70,7 +219,6 @@ function generateSuite(array $args)
70219
throw new Exception("Please provide suite name(s) after generate:suite command");
71220
}
72221

73-
require 'tests'. DIRECTORY_SEPARATOR . 'functional' . DIRECTORY_SEPARATOR . '_bootstrap.php';
74222
$sg = \Magento\FunctionalTestingFramework\Suite\SuiteGenerator::getInstance();
75223

76224
foreach ($args as $arg) {
@@ -85,18 +233,18 @@ function generateSuite(array $args)
85233
*/
86234
function functional()
87235
{
88-
$this->_exec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run functional --skip-group skip');
236+
$this->_exec(VENDOR_BIN_PATH . 'codecept run functional');
89237
}
90238

91239
/**
92-
* Run all Tests with the specified @group tag, excluding @group 'skip'.
240+
* Run all Tests with the specified @group tag'.
93241
*
94242
* @param string $args
95243
* @return void
96244
*/
97245
function group($args = '')
98246
{
99-
$this->taskExec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run functional --verbose --steps --skip-group skip --group')->args($args)->run();
247+
$this->taskExec(VENDOR_BIN_PATH . 'codecept run functional --verbose --steps --group')->args($args)->run();
100248
}
101249

102250
/**
@@ -107,7 +255,7 @@ function group($args = '')
107255
*/
108256
function folder($args = '')
109257
{
110-
$this->taskExec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run functional')->args($args)->run();
258+
$this->taskExec(VENDOR_BIN_PATH . 'codecept run functional')->args($args)->run();
111259
}
112260

113261
/**
@@ -117,7 +265,7 @@ function folder($args = '')
117265
*/
118266
function example()
119267
{
120-
$this->_exec('.' . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'codecept run --group example --skip-group skip');
268+
$this->_exec(VENDOR_BIN_PATH . 'codecept run --group example');
121269
}
122270

123271
/**

dev/tests/acceptance/codeception.dist.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@ paths:
55
tests: tests
66
log: tests/_output
77
data: tests/_data
8-
support: vendor/magento/magento2-functional-testing-framework/src/Magento/FunctionalTestingFramework
9-
envs: vendor/magento/magento2-functional-testing-framework/etc/_envs
8+
support: "%REPLACED IN BUILD:PROJECT%"
9+
envs: "%REPLACED IN BUILD:PROJECT%"
1010
settings:
1111
bootstrap: _bootstrap.php
1212
colors: true
1313
memory_limit: 1024M
1414
extensions:
1515
enabled:
1616
- Codeception\Extension\RunFailed
17-
- Yandex\Allure\Adapter\AllureAdapter
17+
- Magento\FunctionalTestingFramework\Extension\TestContextExtension
18+
- Magento\FunctionalTestingFramework\Allure\Adapter\MagentoAllureAdapter
1819
config:
1920
Yandex\Allure\Adapter\AllureAdapter:
2021
deletePreviousResults: true

dev/tests/acceptance/composer.json

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,8 @@
1616
}
1717
],
1818
"require": {
19-
"allure-framework/allure-codeception": "~1.2.6",
20-
"codeception/codeception": "~2.3.4",
21-
"consolidation/robo": "^1.0.0",
22-
"symfony/process": ">=2.7 <3.4",
23-
"henrikbjorn/lurker": "^1.2",
24-
"magento/magento2-functional-testing-framework": "~2.1.1",
2519
"php": "~7.1.3||~7.2.0",
26-
"vlucas/phpdotenv": "~2.4"
20+
"magento/magento2-functional-testing-framework": "~2.2.0"
2721
},
2822
"autoload": {
2923
"psr-4": {

0 commit comments

Comments
 (0)