Skip to content

MQE-1703: Implicit Suite Generation for Tests #434

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Sep 5, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Magento\FunctionalTestingFramework\Util\Filesystem\DirSetupUtil;
use Magento\FunctionalTestingFramework\Util\TestGenerator;
use Magento\FunctionalTestingFramework\Config\MftfApplicationConfig;
use Magento\FunctionalTestingFramework\Suite\Handlers\SuiteObjectHandler;

class BaseGenerateCommand extends Command
{
Expand Down Expand Up @@ -67,4 +68,39 @@ protected function removeGeneratedDirectory(OutputInterface $output, bool $verbo
}
}
}

/**
* Returns an array of test configuration to be used as an argument for generation of tests
* @param array $tests
* @return false|string
* @throws \Magento\FunctionalTestingFramework\Exceptions\XmlException
*/

protected function getTestAndSuiteConfiguration(array $tests)
{
$testConfiguration['tests'] = null;
$testConfiguration['suites'] = null;
$testsReferencedInSuites = SuiteObjectHandler::getInstance()->getAllTestReferences();
$suiteToTestPair = [];

foreach($tests as $test) {
if (array_key_exists($test, $testsReferencedInSuites)) {
$suites = $testsReferencedInSuites[$test];
foreach ($suites as $suite) {
$suiteToTestPair[] = "$suite:$test";
}
}
// configuration for tests
else {
$testConfiguration['tests'][] = $test;
}
}
// configuration for suites
foreach ($suiteToTestPair as $pair) {
list($suite, $test) = explode(":", $pair);
$testConfiguration['suites'][$suite][] = $test;
}
$testConfigurationJson = json_encode($testConfiguration);
return $testConfigurationJson;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,18 @@ protected function execute(InputInterface $input, OutputInterface $output)
{
$tests = $input->getArgument('name');
$config = $input->getOption('config');
$json = $input->getOption('tests');
$json = $input->getOption('tests'); // for backward compatibility
$force = $input->getOption('force');
$time = $input->getOption('time') * 60 * 1000; // convert from minutes to milliseconds
$debug = $input->getOption('debug') ?? MftfApplicationConfig::LEVEL_DEVELOPER; // for backward compatibility
$remove = $input->getOption('remove');
$verbose = $output->isVerbose();
$allowSkipped = $input->getOption('allowSkipped');

if (!empty($tests)) {
$json = $this->getTestAndSuiteConfiguration($tests);
}

if ($json !== null && !json_decode($json)) {
// stop execution if we have failed to properly parse any json passed in by the user
throw new TestFrameworkException("JSON could not be parsed: " . json_last_error_msg());
Expand Down Expand Up @@ -100,9 +104,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$testManifest->createTestGroups($time);
}

if (empty($tests)) {
SuiteGenerator::getInstance()->generateAllSuites($testManifest);
}
SuiteGenerator::getInstance()->generateAllSuites($testManifest);

$testManifest->generate();

Expand Down
44 changes: 36 additions & 8 deletions src/Magento/FunctionalTestingFramework/Console/RunTestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,35 @@ protected function execute(InputInterface $input, OutputInterface $output): int
);
}

$testConfiguration = $this->getTestAndSuiteConfiguration($tests);

if (!$skipGeneration) {
$command = $this->getApplication()->find('generate:tests');
$args = [
'--tests' => json_encode([
'tests' => $tests,
'suites' => null
]),
'--tests' => $testConfiguration,
'--force' => $force,
'--remove' => $remove,
'--debug' => $debug,
'--allowSkipped' => $allowSkipped
];
$command->run(new ArrayInput($args), $output);
}
// tests with resolved suite references
$resolvedTests = $this->resolveSuiteReferences($testConfiguration);

$returnCode = 0;
$codeceptionCommand = realpath(PROJECT_ROOT . '/vendor/bin/codecept') . ' run functional ';
$testsDirectory = TESTS_MODULE_PATH . DIRECTORY_SEPARATOR . TestGenerator::GENERATED_DIR . DIRECTORY_SEPARATOR;
$returnCode = 0;
//execute only tests specified as arguments in run command
foreach ($tests as $test) {
$testGroup = TestGenerator::DEFAULT_DIR . DIRECTORY_SEPARATOR;
$testName = $test . 'Cest.php';
foreach ($resolvedTests as $test) {
//set directory as suite name for tests in suite, if not set to "default"
if (strpos($test, ':')) {
list($testGroup, $testName) = explode(":", $test);
} else {
list($testGroup, $testName) = [TestGenerator::DEFAULT_DIR, $test];
}
$testGroup = $testGroup . DIRECTORY_SEPARATOR;
$testName = $testName . 'Cest.php';
if (!realpath($testsDirectory . $testGroup . $testName)) {
throw new TestFrameworkException(
$testName . " is not available under " . $testsDirectory . $testGroup
Expand All @@ -104,4 +111,25 @@ function ($type, $buffer) use ($output) {
}
return $returnCode;
}

/**
* Get an array of tests with resolved suite references from $testConfiguration
* eg: if test is referenced in a suite, it'll be stored in format suite:test
* @param string $testConfigurationJson
* @return array
*/
private function resolveSuiteReferences($testConfigurationJson)
{
$testConfiguration = json_decode($testConfigurationJson, true);
$testsArray = $testConfiguration['tests'] ?? [];
$suitesArray = $testConfiguration['suites'] ?? [];
$testArrayBuilder = [];

foreach ($suitesArray as $suite => $tests) {
foreach ($tests as $test) {
$testArrayBuilder[] = "$suite:$test";
}
}
return array_merge($testArrayBuilder, $testsArray);
}
}