Hello everyone!

We have been investing plenty of personal time and energy for many years to share our knowledge with you all. However, we now need your help to keep this blog running. All you have to do is just click one of the adverts on the site, otherwise it will sadly be taken down due to hosting etc. costs. Thank you.

If you follow example below you can test your symfony commands with behat.


HelloCommand


namespace My\HelloBundle\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class HelloCommand extends Command
{
protected function configure()
{
$this
->setName('say:hello')
->setDescription('Say hello to someone')
->addOption('name', null, InputOption::VALUE_REQUIRED, "Person's name")
->addOption('surname', null, InputOption::VALUE_OPTIONAL, "Person's surname");
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$name = $input->getOption('name');
$surname = $input->getOption('surname');
$message = $surname ? sprintf('Hello %s %s.', $name, $surname) : sprintf('Hello %s.', $name);

$output->writeln($message);
}
}

Usage


$ app/console say:hello --name=inanzzz
$ app/console say:hello --name=inanzzz --surname=brother

CommandContext


namespace My\HelloBundle\Features\Context;

use Behat\Gherkin\Node\TableNode;
use Behat\Symfony2Extension\Context\KernelAwareContext;
use Exception;
use My\HelloBundle\Command\HelloCommand;
use LogicException;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\HttpKernel\KernelInterface;

class CommandContext implements KernelAwareContext
{
/** @var KernelInterface */
private $kernel;
/** @var Application */
private $application;
/** @var Command */
private $command;
/** @var CommandTester */
private $commandTester;
/** @var string */
private $commandException;
/** @var array */
private $options;

/**
* @param KernelInterface $kernel
*/
public function setKernel(KernelInterface $kernel)
{
$this->kernel = $kernel;
}

/**
* @param TableNode $tableNode
*
* @When /^I run the "say:hello" command with options:$/
*/
public function iRunTheCommandWithOptions(TableNode $tableNode)
{
$this->setApplication();
$this->addCommand(new HelloCommand());
$this->setCommand('say:hello');
$this->setOptions($tableNode);

try {
$this->getTester($this->command)->execute($this->options);
} catch (Exception $exception) {
$path = explode('\\', get_class($exception));
$this->commandException = array_pop($path);
}
}

/**
* @param string $expectedOutput
*
* @Then /^the command output should be "([^"]*)"$/
*/
public function theCommandOutputShouldBe($expectedOutput)
{
$current = trim($this->commandTester->getDisplay());
if ($current != $expectedOutput) {
throw new LogicException(sprintf('Current output is: [%s]', $current));
}
}

/**
* @param string $expectedException
*
* @Then /^the command exception should be "([^"]*)"$/
*/
public function theCommandExceptionShouldBe($expectedException)
{
if ($this->commandException != $expectedException) {
throw new LogicException(sprintf('Current exception is: [%s]', $this->commandException));
}
}

private function setApplication()
{
$this->application = new Application($this->kernel);
}

private function addCommand(Command $command)
{
$this->application->add($command);
}

private function setCommand($commandName)
{
$this->command = $this->application->find($commandName);
}

private function setOptions(TableNode $tableNode)
{
$options = [];
foreach ($tableNode->getRowsHash() as $key => $value) {
$options[$key] = $value;
}

$this->options = $options;
}

private function getTester(Command $command)
{
$this->commandTester = new CommandTester($command);

return $this->commandTester;
}
}

Commands feature


$ bin/behat src/My/HelloBundle/Features/Commands.feature

Feature: ......

Scenario: I can run command with only compulsory options to confirm it's terminal output.
Given I run the "say:hello" command with options:
| --name | inanzzz |
Then the command output should be "Hello inanzzz."

Scenario: I can run command with all available options to confirm it's terminal output.
Given I run the "say:hello" command with options:
| --name | inanzzz |
| --surname | brother |
Then the command output should be "Hello inanzzz brother."

Scenario: I cannot run command with invalid options.
Given I run the "say:hello" command with options:
| --nickname | inanzzz |
Then the command exception should be "InvalidOptionException"

Test


Feature: ...

Scenario: I can run command with only compulsory options to confirm it's terminal output.
Given I run the "say:hello" command with options:
| --name | inanzzz |
Then the command output should be "Hello inanzzz."

Scenario: I can run command with all available options to confirm it's terminal output.
Given I run the "say:hello" command with options:
| --name | inanzzz |
| --surname | brother |
Then the command output should be "Hello inanzzz brother."

Scenario: I cannot run command with invalid options.
Given I run the "say:hello" command with options:
| --nickname | inanzzz |
Then the command exception should be "InvalidOptionException"

3 scenarios (3 passed)
6 steps (6 passed)
0m8.79s (Can not calculate memory usage)