Behat & Symfony's Process component

Posted on Monday January 23, 2017

Here's a super-quick way of using the Symfony Process Component in Behat Contexts to run processes in the background.

Chatting with a friend (@pieceofthepie) in the PHP East Midlands slack team and they said this:

The CI I’m playing with has a test step the needs me to start the php server, so I’m doing it in bash with a &

It works, but doing it 'properly' would maybe be better.

Now, we could argue the meaning of 'properly' all day (their method works, so what's the problem?) but I thought I'd come up with an alternative for them.

Running background processes in Behat scenarios is something I'd done a number of times before in projects (scenarios required job workers to be running in the background to end-to-end test some async feature within an application) so this wouldn't be too difficult to do with the Symfony Process Component.

I quickly came up with the following for them:


namespace App\Context;

use Behat\Behat\Context\Context;
use Symfony\Component\Process\Process;

class PhpServerContext implements Context
    const TIMEOUT = 10;
     * @var Process
    protected $process;
     * @BeforeScenario @run-server
    public function startServerProcess()
        $this->process = new Process('exec php -S localhost:8000 -t /path/to/my/public/directory');
     * @AfterScenario @run-server
    public function stopServerProcess()
        $this->process->stop(self::TIMEOUT, SIGTERM);
        $this->process = null;

Now tagging a scenario / feature with: @run-server will mean that the PHP built-in webserver will be started before the scenario runs and will be listening on port :8000. It'll then stop the server when the scenario is finished - job done!

You could take this a step further and have it configurable for ports & docroot, maybe check if something is listening on that port already. Maybe have it run for the full suite, depends on your needs / use case.

Built with Tailwind CSS using Hugo hosted on Netlify
© 2020 Matt Brunt