Codeception / module-symfony

Codeception module for testing apps using Symfony framework
MIT License
88 stars 24 forks source link

runSymfonyConsoleCommand with options is sometimes ignoring the options #172

Closed MarkDaleman closed 6 months ago

MarkDaleman commented 10 months ago

Hello 👋

I'm facing a problem when loading migrations from my Module. I want to hook in on the _beforeSuite with a Symfony command to load my fixtures and such.

The interesting thing is, one part works fine while the other part doesn't.

I'm trying to run the following code:

$symfony->runSymfonyConsoleCommand('doctrine:fixtures:load', ['--no-interaction'=>true])

When I print this I get the following rest:

 Careful, database "db_name_here_test" will be purged. Do you want to continue? (yes/no) [no]:\n
 > 

I also run other commands like:

$symfony->runSymfonyConsoleCommand('doctrine:database:drop',['--if-exists'=>true, '--force'=>true]);
$symfony->runSymfonyConsoleCommand('doctrine:database:create');
$symfony->runSymfonyConsoleCommand('doctrine:migrations:migrate', ['--no-interaction'=>true]);

And those work fine (and without user interaction).

So the question is, do I something very wrong or is there a possible bug?

More information

What I've tried is:

What kind of software I'm using:

My module's full code for reference:

<?php

namespace App\Tests\Helper;

use Codeception\Exception\ModuleException;
use Codeception\Module;

class MyModule extends Module
{
    /**
     * @throws ModuleException
     */
    public function _beforeSuite(array $settings = []): void
    {
        /** @var Module\Symfony  $symfony */
        $symfony = $this->getModule('Symfony');
        $symfony->runSymfonyConsoleCommand('doctrine:database:drop',['--if-exists'=>true, '--force'=>true]);
        $symfony->runSymfonyConsoleCommand('doctrine:database:create');
        $symfony->runSymfonyConsoleCommand('doctrine:migrations:migrate', ['--no-interaction'=>true]);
        $symfony->runSymfonyConsoleCommand('doctrine:fixtures:load', ['--no-interaction'=>true]);
    }
}
mkilmanas commented 9 months ago

To confirm and clarify the issue here: the problem exists only for some key options that are handled in the special way

E.g. --no-interaction should make $input->isInteractive() === false, similarly none of the -v, -vv, -vvv, --verbose options work as they would also be setting the verbosity level on the Output object.

In particular:

TavoNiievez commented 6 months ago

Hi @MarkDaleman ,

I have opened a Pull Request https://github.com/Codeception/module-symfony/pull/188 to resolve this issue. with it, a test like the following now works correctly:

        $output = $I->runSymfonyConsoleCommand('doctrine:fixtures:load', ['-q']);
        $I->assertIsEmpty($output);
        $numRecords = $I->grabNumRecords(User::class);
        $I->assertSame(4, $numRecords);

@mkilmanas ' explanation was quite helpful in writing the code.

For me it was important to make this change without changing the signature of the runSymfonyConsoleCommand method, this way I avoid creating BC and having to release a new major version just for this.

This manual parsing is not the nicest solution, and I guess Symfony itself must do something similar in its own code, but for the purposes of solving this issue it works quite well.

@mkilmanas If something inhibited you from submitting a PR yourself for this having such a clear understanding of the problem please let me know, likewise if you can do a little Code Review to the PR I'd appreciate it.

Thanks a lot to both of you!

mkilmanas commented 6 months ago

@TavoNiievez thanks for the PR - looks good to me!

I did not get involved with this as figuring out the cause of the problem is one thing and providing a solution that would be in line with the rest of the module is another - I am not that familiar with the internals of codeception or its modules.

TavoNiievez commented 6 months ago

Released as 3.3.2

Thank you!