25

Is there a way to run a console command from a Symfony 2 test case? I want to run the doctrine commands for creating and dropping schemas.

0

4 Answers 4

77

This documentation chapter explains how to run commands from different places. Mind, that using exec() for your needs is quite dirty solution...

The right way of executing console command in Symfony2 is as below:

Option one

use Symfony\Bundle\FrameworkBundle\Console\Application as App;
use Symfony\Component\Console\Tester\CommandTester;

class YourTest extends WebTestCase
{
    public function setUp()
    {
        $kernel = $this->createKernel();
        $kernel->boot();

        $application = new App($kernel);
        $application->add(new YourCommand());

        $command = $application->find('your:command:name');
        $commandTester = new CommandTester($command);
        $commandTester->execute(array('command' => $command->getName()));
    }
}

Option two

use Symfony\Component\Console\Input\StringInput;
use Symfony\Bundle\FrameworkBundle\Console\Application;

class YourClass extends WebTestCase
{
    protected static $application;

    public function setUp()
    {
        self::runCommand('your:command:name');
        // you can also specify an environment:
        // self::runCommand('your:command:name --env=test');
    }

    protected static function runCommand($command)
    {
        $command = sprintf('%s --quiet', $command);    

        return self::getApplication()->run(new StringInput($command));
    }

    protected static function getApplication()
    {
        if (null === self::$application) {
            $client = static::createClient();

            self::$application = new Application($client->getKernel());
            self::$application->setAutoExit(false);
        }

        return self::$application;
    }
}

P.S. Guys, don't shame Symfony2 with calling exec()...

Sign up to request clarification or add additional context in comments.

2 Comments

This is the right answer as mentioned on the official Symfony2 documentantion under "Testing Commands": symfony.com/doc/current/components/console/…
@FrancescoCasula link is broken - new location: symfony.com/doc/current/console.html#testing-commands
5

The docs tell you the suggested way to do it. The example code is pasted below:

protected function execute(InputInterface $input, OutputInterface $output)
{
    $command = $this->getApplication()->find('demo:greet');

    $arguments = array(
        'command' => 'demo:greet',
        'name'    => 'Fabien',
        '--yell'  => true,
    );

    $input = new ArrayInput($arguments);
    $returnCode = $command->run($input, $output);

    // ...
}

1 Comment

This is for running a command from another command, not from a test case.
0

Yes, if your directory structure looks like

/symfony
    /app
    /src

then you would run

phpunit -c app/phpunit.xml.dist

from your unit tests you can run php commands either by using

passthru("php app/console [...]") (http://php.net/manual/en/function.passthru.php)
exec("php app/console [...]") (http://www.php.net/manual/en/function.exec.php)

or by putting the command in back ticks

php app/consode [...]

If you are running the unit tests from a directory other than symofny, you'll have to adjust the relative path to the app directory for it to work.

To run it from the app:

// the document root should be the web folder
$root = $_SERVER['DOCUMENT_ROOT'];

passthru("php $root/../app/console [...]");

6 Comments

Isn't there a way of running from inside the application? I'm trying to create completely isolated tests.
Also, i want the command to run on a specific environment (test).
Yes, you could put that code inside a model or entity, but you would have to use $_SERVER['DOCUMENT_ROOT']; to get the path to app. I'll edit my answer
im not sure how to access the environment from the app, but if there's a way you can do it, just put the passthru inside an if statement that checks for the environment
I don't know why this answer gets hate, it is how Symfony documents it: symfony.com/doc/7.2/testing/bootstrap.html
|
-2

The documentation has been updated since my last answer to reflect the proper Symfony 2 way of calling an existing command:

http://symfony.com/doc/current/components/console/introduction.html#calling-an-existing-command

4 Comments

It is not true Symfony way
It's not even a good way as you cannot parse the ouptut correctly. You also might run into problems with the environment (what if php is not in the path of the user running the tests?).
Please, don't do it this way!
Note that the original question is not about testing commands, but about executing commands during tests. Like droping / recreating datas, validating users without email validation, etc. Please read carefully before downgrading.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.