Получение вывода команды symfony через shell_exec / ApplicationTester и т.д. в модульном тестировании symfony

#symfony #command #phpunit #shell-exec

#symfony #команда #phpunit #shell-exec

Вопрос:

Я хотел бы запустить команду в отдельном процессе из модульного теста и получить ее выходные данные. Я протестировал несколько вариантов, таких как using shell_exec или ApplicationTester -class . Хотя команда, очевидно, выполняется (я проверил, вставив некоторые побочные эффекты), ее вывод не может быть получен при выполнении из модульного теста.

Однако, если я создаю небольшой автономный php-файл (см. Ниже runDummyCmd.php ), который содержит соответствующий shell_exec , я получаю выходные данные команды symfony.

Как воспроизвести

Фиктивная команда:

 <?php


namespace AppCommand;

use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleOutputOutputInterface;

class DummyCommand extends Command
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this
            ->setName('app:dummycmd')
            ->setDescription('Can be used for testing commands')
            ->setHelp('Does a simple output.');
    }

    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('Test!');
        return 0;
    }
}
  

Тестовый пример:

 class MyTest extends MyKernelTestCase
{
    protected $projectDir;

    protected function setUp(): void
    {
        parent::setUp();

        $this->projectDir = static::$container->getParameter('kernel.project_dir');
    }

    public function testGetOutputOfCommand() {
        $cmd = 'env APP_ENV=test '. $this->projectDir . '/bin/console app:dummycmd';

        dump($cmd);
        $output = shell_exec($cmd);

        dump($output);
    }
}
  

runDummyCmd.php:

 <?php
$cmd = 'env APP_ENV=test bin/console app:dummycmd';

var_dump($cmd);
$output = shell_exec($cmd);

var_dump($output);
?>
  

Выводит
Вывод модульного теста:

 "env APP_ENV=test PROJECT_DIR/bin/console app:dummycmd"
null
  

Вывод выполнения runDummyCmd.php на консоли:

 string(41) "env APP_ENV=test bin/console app:dummycmd"
string(6) "Test!
"
  

Комментарии:

1. Однако, если я неправильно пишу команду и, следовательно bin/console , выдаю ошибку, на вывод передаются соответствующие сообщения об ошибках.

2. Я загрузил вашу команду и тест в новый проект symfony, и он сразу же заработал. Какой результат вы получаете, когда перенаправляете stderr в stdout ( $cmd = 'env APP_ENV=test '. $this->projectDir . '/bin/console app:dummycmd 2>amp;1'; )?

3. Спасибо за ваш тест! Я попытался перенаправить stderr, и это тоже не сработало, результат по-прежнему равен нулю.

4. Странно. Код завершения выполнения тоже был бы интересен. Поскольку вы все равно используете symfony, вы можете запустить команду с помощью компонента process . Это дает вам удобный способ доступа к stdout, stderr и коду выхода.

5. Извините за поздний ответ: я выполнил команду с помощью exec() и получил как выходные данные, так и код выхода, который равен 0. Как я писал в своем первоначальном вопросе, команда выполняется, что можно заметить из-за ее побочных эффектов. Это очень странно…

Ответ №1:

Вы пробовали класс CommandTester?

 $command = $application->find('app:dummycmd');
$commandTester = new CommandTester($command);
$commandTester->execute([
   'command'  => $command->getName()
]);
$output = $commandTester->getDisplay();
  

Комментарии:

1. Да, я использовал это раньше, но это не порождает дочерний процесс, который важен для меня.