2012-04-30 155 views

回答

-3

該文檔已更新自從我上次的答案,以反映調用現有命令的正確Symfony的2路:

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

+0

像魅力一樣工作,謝謝。 – vinnylinux

+12

這不是真正的Symfony方式 –

+6

它甚至不是一個好方法,因爲你不能正確地解析ouptut。您也可能遇到環境問題(如果php不在用戶運行測試的路徑中,該怎麼辦?)。 – Sgoettschkes

-1

是的,如果你的目錄結構看起來像

/symfony 
    /app 
    /src 

那麼你要麼使用

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) 
命令運行

phpunit -c app/phpunit.xml.dist

從你的單元測試,你可以運行PHP

或將命令放回

php app/consode [...]

如果您正在從高於symofny其他目錄的單元測試,你就必須相對路徑調整到app目錄爲它工作。

要從應用程序運行:

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

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

是否存在從應用程序內部運行的方式?我正在嘗試創建完全隔離的測試。 – vinnylinux

+0

另外,我想讓命令在特定環境(測試)上運行。 – vinnylinux

+0

是的,您可以將該代碼放入模型或實體中,但您必須使用'$ _SERVER ['DOCUMENT_ROOT'];'獲取應用程序的路徑。我將編輯我的答案 – ContextSwitch

68

documentation chapter解釋瞭如何從不同地方運行命令。記住,使用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; 
    } 
} 

P.S.夥計們,不要羞恥Symfony2與呼籲exec() ...

+1

正如在「測試命令」下的官方Symfony2文檔中提到的那樣,這是正確的答案:http://symfony.com/doc/current/components/console/introduction.html#testing-commands –

+1

同樣,問題不是關於測試命令... – Moonchild

+0

@FrancescoCasula鏈接被破壞 - 新的位置:http://symfony.com/doc/current/console.html#testing-commands –

5

docs告訴你建議的方式來做到這一點。示例代碼粘貼如下:

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); 

    // ... 
} 
+0

我已經參考該章節,其實:) –

+0

哦,哦,沒有注意到這一點。 – Squazic

+5

這是爲了運行來自另一個命令的命令,而不是來自測試用例。 – Machiel