#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. Да, я использовал это раньше, но это не порождает дочерний процесс, который важен для меня.