从 Symfony 2 测试用例运行控制台命令


Running console command from a Symfony 2 test case

有没有办法从Symfony 2测试用例运行控制台命令?我想运行用于创建和删除架构的 doctrine 命令。

本文档章节介绍如何从不同位置运行命令。请注意,使用exec()满足您的需求是非常肮脏的解决方案......

在 Symfony2 中执行控制台命令的正确方法如下:

备选方案一

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()));
    }
}
<小时 />

备选方案二

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;
    }
}
<小时 />

附言伙计们,不要因为打电话给exec()而羞辱 Symfony2 ......

文档会告诉您建议的方法。示例代码粘贴如下:

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);
    // ...
}

是的,如果您的目录结构看起来像

/symfony
    /app
    /src

然后你会跑

phpunit -c app/phpunit.xml.dist

从单元测试中,您可以使用以下方法运行 PHP 命令

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)

或者将命令放在反引号中

php app/consode [...]

如果从 symofny 以外的目录运行单元测试,则必须调整应用目录的相对路径才能使其正常工作。

要从应用程序运行它,请执行以下操作:

// the document root should be the web folder
$root = $_SERVER['DOCUMENT_ROOT'];
passthru("php $root/../app/console [...]");

自从我上次回答以来,文档已经更新,以反映调用现有命令的正确Symfony 2方式:

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