Ejecutar comando de consola desde un caso de prueba de Symfony 2

3 minutos de lectura

avatar de usuario de vinnylinux
vinnylinux

¿Hay alguna forma de ejecutar un comando de consola desde un caso de prueba de Symfony 2? Quiero ejecutar los comandos de la doctrina para crear y descartar esquemas.

Avatar de usuario de Vitalii Zurian
vitalii zurian

Este capitulo de documentacion explica cómo ejecutar comandos desde diferentes lugares. Mente, que usando exec() para sus necesidades es una solución bastante sucia…

los manera correcta de ejecutar el comando de la consola en Symfony2 es el siguiente:

Opcion uno

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

Opción dos

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

PD Chicos, no avergüencen a Symfony2 con llamadas exec()

los documentos decirte la forma sugerida de hacerlo. El código de ejemplo se pega a continuación:

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

    // ...
}

  • Esto es para ejecutar un comando desde otro comando, no desde un caso de prueba.

    – Maquiel

    24 de junio de 2013 a las 23:32

Avatar de usuario de ContextSwitch
Cambio de contexto

Sí, si la estructura de su directorio se parece a

/symfony
    /app
    /src

entonces correrías

phpunit -c app/phpunit.xml.dist

desde sus pruebas unitarias, puede ejecutar comandos php usando

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)

o poniendo el comando en ticks traseros

php app/consode [...]

Si está ejecutando las pruebas unitarias desde un directorio que no sea Symofny, deberá ajustar la ruta relativa al directorio de la aplicación para que funcione.

Para ejecutarlo desde la aplicación:

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

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

  • ¿No hay una forma de ejecutar desde dentro de la aplicación? Estoy tratando de crear pruebas completamente aisladas.

    – vinnylinux

    30 de abril de 2012 a las 17:58

  • Además, quiero que el comando se ejecute en un entorno específico (prueba).

    – vinnylinux

    30 de abril de 2012 a las 18:11

  • Sí, podría poner ese código dentro de un modelo o entidad, pero tendría que usar $_SERVER['DOCUMENT_ROOT']; para obtener la ruta a la aplicación. Editaré mi respuesta

    – Cambio de contexto

    30 de abril de 2012 a las 19:48


  • No estoy seguro de cómo acceder al entorno desde la aplicación, pero si hay alguna manera de hacerlo, simplemente coloque el passthru dentro de una declaración if que verifique el entorno.

    – Cambio de contexto

    30 de abril de 2012 a las 19:52

  • exec() no funcionará ya que no estará en el contenedor de prueba.

    – Jake Silvestre

    3 de abril de 2017 a las 0:04

Avatar de usuario de Klaus S.
klaus s

La documentación se ha actualizado desde mi última respuesta para reflejar la forma correcta de Symfony 2 de llamar a un comando existente:

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

¿Ha sido útil esta solución?