Matok's PHP Blog

Symfony: Verbosity level in command testing

article image

When I make symfony command I do basically two things. Firstly I prepare simple tests mostly about command line arguments. Rest of stuff that command uses is tested elsewhere. Second thing I like is to add some information, what command is doing during execution, this is achieved by verbosity level: -v|vv|vvv. This is good because when command is running like 12 hours is desirable to have some information.

Example commad

namespace Matok\Bundle\BlogBundle\Command;

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

class VerbosityCommand extends Command
{
    protected function configure()
    {
        $this
            ->setName('matok:blog:verbosity')
            ->addOption('yell');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $message = 'Hello Matok! Your blog is the best <3';

        if ($input->getOption('yell')) {
            if ($output->getVerbosity() > OutputInterface::VERBOSITY_NORMAL) {
                $output->writeln('** Running with "yell" option');
            }

            $message = strtoupper($message);
        }

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

When I run
$ php bin/console matok:blog:verbosity
output is:
Hello Matok! Your blog is the best <3
When I run
$ php bin/console matok:blog:verbosity --yell -v
output is:
** Running with "yell" option
HELLO MATOK! YOUR BLOG IS THE BEST <3

This is beautiful, isn't it?

Let's test it

When you follow symfony documentation, you can do someting like this:

// namespace & uses ...
class VerbosityCommandTest extends KernelTestCase
{
      public function testVerboseOptionPrintsInfoMessage()
      {
          self::bootKernel();
          $application = new Application(self::$kernel);
          $application->add(new VerbosityCommand());
          $command = $application->find('matok:blog:verbosity');
          $commandTester = new CommandTester($command);
          $commandTester->execute(array(
              'command'  => $command->getName(),
              '--yell' => true,
              '-v' => true,
          ));

          $output = $commandTester->getDisplay();
          $this->assertContains('** Running with "yell" option', $output);
      }
}

And you will be surprised like I was because this is not working:

Failed asserting that 'HELLO MATOK! YOUR BLOG IS THE BEST <3
' contains "** Running with "yell" option".

This looks like --yell option is working but -v ins't. The answer lie down in the deeps of command tester... this wasn't hard to find. So we do little rewrite:

// namespace & uses ...
class VerbosityCommandTest extends KernelTestCase
{
    public function testWithVerboseExecute2()
    {
        self::bootKernel();
        $application = new Application(self::$kernel);
        $application->add(new VerbosityCommand());
        $command = $application->find('matok:blog:verbosity');
        $commandTester = new CommandTester($command);
        $commandTester->execute(array(
            'command'  => $command->getName(),
            '--yell' => true,
        ), array(
            'verbosity' => OutputInterface::VERBOSITY_VERBOSE
        ));

        $output = $commandTester->getDisplay();
        $this->assertContains('** Running with "yell" option', $output);
    }
}

...and the result voilà: OK (1 test, 1 assertion) (in my console is nicely green color). This is how you can run command in tests or from controller with verbosity options. To keep trend with my previous articles one last sentence: Don't fucking play around with some stupid --show-more, --gimmefuckinginfo custom arguments just for all that you don't know to find this in symfony source code, because for this purpose verbosity mode exists and it will be exist long after glory of symfony will be vanished.


If you like this article then mark it as helpful to let others know it's worth to read. Otherwise leave me a feedback/comment and we can talk about it.

I'm foreigner. Where I live my friends call me Maťok.


Comments - Coming Soon