Skip to content

MQE-1755: mftf run:test Test1 Test2 does not run before/after hooks c… #448

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 5 commits into from
Sep 13, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 74 additions & 45 deletions src/Magento/FunctionalTestingFramework/Console/RunTestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@

class RunTestCommand extends BaseGenerateCommand
{
/**
* The return code. Determined by all tests that run.
*
* @var integer
*/
private $returnCode = 0;

/**
* Configures the current command.
*
Expand All @@ -44,8 +51,6 @@ protected function configure()
* @param OutputInterface $output
* @return integer
* @throws \Exception
*
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
Expand Down Expand Up @@ -76,60 +81,84 @@ protected function execute(InputInterface $input, OutputInterface $output): int
];
$command->run(new ArrayInput($args), $output);
}
// tests with resolved suite references
$resolvedTests = $this->resolveSuiteReferences($testConfiguration);

$testConfigArray = json_decode($testConfiguration, true);

if (isset($testConfigArray['tests'])) {
$this->runTests($testConfigArray['tests'], $output);
}

if (isset($testConfigArray['suites'])) {
$this->runTestsInSuite($testConfigArray['suites'], $output);
}

return $this->returnCode;
}

/**
* Run tests not referenced in suites
*
* @param array $tests
* @param OutputInterface $output
* @return void
* @throws TestFrameworkException
*/
private function runTests(array $tests, OutputInterface $output)
{
$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 ($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)) {
$testsDirectory = TESTS_MODULE_PATH .
DIRECTORY_SEPARATOR .
TestGenerator::GENERATED_DIR .
DIRECTORY_SEPARATOR .
TestGenerator::DEFAULT_DIR .
DIRECTORY_SEPARATOR ;

foreach ($tests as $test) {
$testName = $test . 'Cest.php';
if (!realpath($testsDirectory . $testName)) {
throw new TestFrameworkException(
$testName . " is not available under " . $testsDirectory . $testGroup
$testName . " is not available under " . $testsDirectory
);
}
$fullCommand = $codeceptionCommand . $testsDirectory . $testGroup . $testName . ' --verbose --steps';
$process = new Process($fullCommand);
$process->setWorkingDirectory(TESTS_BP);
$process->setIdleTimeout(600);
$process->setTimeout(0);

$returnCode = max($returnCode, $process->run(
function ($type, $buffer) use ($output) {
$output->write($buffer);
}
));
$fullCommand = $codeceptionCommand . $testsDirectory . $testName . ' --verbose --steps';
$this->returnCode = max($this->returnCode, $this->executeTestCommand($fullCommand, $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
* Run tests referenced in suites within suites' context.
*
* @param array $suitesConfig
* @param OutputInterface $output
* @return void
*/
private function resolveSuiteReferences($testConfigurationJson)
private function runTestsInSuite(array $suitesConfig, OutputInterface $output)
{
$testConfiguration = json_decode($testConfigurationJson, true);
$testsArray = $testConfiguration['tests'] ?? [];
$suitesArray = $testConfiguration['suites'] ?? [];
$testArrayBuilder = [];

foreach ($suitesArray as $suite => $tests) {
foreach ($tests as $test) {
$testArrayBuilder[] = "$suite:$test";
}
$codeceptionCommand = realpath(PROJECT_ROOT . '/vendor/bin/codecept') . ' run functional --verbose --steps ';
//for tests in suites, run them as a group to run before and after block
foreach (array_keys($suitesConfig) as $suite) {
$fullCommand = $codeceptionCommand . " -g {$suite}";
$this->returnCode = max($this->returnCode, $this->executeTestCommand($fullCommand, $output));
}
return array_merge($testArrayBuilder, $testsArray);
}

/**
* Runs the codeception test command and returns exit code
*
* @param string $command
* @param OutputInterface $output
* @return integer
*
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
private function executeTestCommand(string $command, OutputInterface $output)
{
$process = new Process($command);
$process->setWorkingDirectory(TESTS_BP);
$process->setIdleTimeout(600);
$process->setTimeout(0);
return $process->run(function ($type, $buffer) use ($output) {
$output->write($buffer);
});
}
}