Setting up Behat on Symfony 5 or higher
Written by sadikoff, and bocharsky-bw
If you're interested in Behat, we have a great tutorial about it! Except that... well... that tutorial is getting old when it comes to getting Behat installed and configured into a modern app.
So how can you use Behat with Symfony 5 or higher? Easy Peasy! Just find a Symfony 5+ project, install and configure Behat, then profit!
Too fast? Ok, let's look at each part, step-by-step.
Install Behat with everything you need
To get started, let's install some packages:
composer require friends-of-behat/mink-extension friends-of-behat/mink-browserkit-driver friends-of-behat/symfony-extension --dev
As you can see, we're using packages from the friends-of-behat
organization.
This setup uses the Symfony extension to make requests directly through Symfony's Client.
Tip
To use Goutte to make real HTTP requests - use this command instead:
composer require friends-of-behat/mink-extension friends-of-behat/mink-browserkit-driver behat/mink-goutte-driver --dev
You may see this warning:
The recipe for this package comes from the "contrib" repository, which is open to community contributions.
Hit "yes" to continue the installation. This recipe has everything you need to run Behat:
|config/
| - services_test.yaml
|features/
| - demo.feature
|tests/
| - Behat/
| - DemoContext.php
|behat.yml.dist
Configure it
But it's still not enough. By default FriendsOfBehat\SymfonyExtension
tries to load
config/bootstrap.php
. But in Symfony 5 or higher, we don't have that file! No problem.
Because Behat is a test system, we can use the same configuration as, for example, PHPUnit. In this case, we can use the same bootstrap file. The only problem is that, unless you already have PHPUnit installed, you won't have this file!
Run:
composer require phpunit --dev
This installs a few packages including a recipe with a shiny new tests/bootstrap.php
file that we can use.
Now we are unstoppable! Adjust your behat.yaml.dist
to use this:
default:
# ...
extensions:
FriendsOfBehat\SymfonyExtension:
bootstrap: tests/bootstrap.php
Now we are ready to test it. Check the features/demo.feature
file out:
Feature:
In order to prove that the Behat Symfony extension is correctly installed
As a user
I want to have a demo scenario
Scenario: It receives a response from Symfony's kernel
When a demo scenario sends a request to "/"
Then the response should be received
It's not too complex, but enough to see if everything works! Run:
./vendor/bin/behat
Woohoo we have Behat superpowers!
PHPUnit Power
You may also want to use PHPUnit's assert functions inside Behat. Cool! We've already installed PHPUnit, so we can immediately use its assertions:
use PHPUnit\Framework\Assert;
final class DemoContext implements Context
{
//...
/**
* @Then the response should be received
*/
public function theResponseShouldBeReceived(): void
{
Assert::assertNotNull($this->response);
}
}
Go to the console and run things again:
./vendor/bin/behat
It's still green! That's a WIN!
Tip
If you have symfony/phpunit-bridge
installed instead of phpunit/phpunit
,
using its built-in assertions is a bit trickier. We recommend installing
phpunit/phpunit
directly.
Real Browser Power
You may ask:
Hey, what about testing in a real browser!?
Let's do it!
For this, we will need some additional tools: Java, Selenium and a browser to test with, like Chrome or Firefox.
Tip
Instead of using Selenium, you could also use Panther via https://github.com/robertfausk/behat-panther-extension. We haven't tried this extension out yet, but in general, working with Panther is great and a bit easier than Selenium.
The "browser" part of the setup is the easiest thing. You probably already have one installed.
But it does require a driver to work properly. For Chrome and Chromium-based browser, you
need chromedriver
. For Firefox, you need geckodriver
.
There are multiple ways to get the driver you need! The easiest is: dbrekelmans/browser-driver-installer -
this package will check your system and automatically download supported drivers into a drivers/
directory in your app. All you need to run is:
composer require --dev dbrekelmans/bdi
./vendor/bin/bdi detect drivers
Otherwise, use your favorite package manager or download it manually from the official ChromeDriver and GeckoDriver repositories.
Then, before running your tests, start it:
# if you downloaded it as a file with dbi
./drivers/chromedriver -v
# or if you installed it with your favorite package manager
chromedriver -v
Next up: selenium server! You can download it from https://www.selenium.dev/downloads/.
Move the downloaded file (e.g. selenium-server-standalone-3.141.59.jar
) to an easily-accessible
folder so you can jump to it.
Executing jar
files requires the Java Runtime to be installed. Check
if it's installed with:
java -version
If you see an error like "Command not found", then install it. Installation, of course, is one of those wonderful things that varies depending on your operating system.
Ok, so we have Java, Selenium and a browser with a driver! Next, open a terminal, go to wherever you put the Selenium file, and run:
java -jar selenium-server-standalone-3.141.59.jar
That will start Selenium, which means that Behat can now operate with your browser. Now we need to tell Behat that we want to use Selenium instead of using Goutte or the Symfony2 extension.
To do this, install the Selenium2 driver:
composer require behat/mink-selenium2-driver --dev
After this finishes, add the following config to behat.yml.dist
:
default:
# ...
extensions:
# ...
Behat\MinkExtension:
# adapt this to whatever the real URL is to your local site
base_url: http://127.0.0.1:8000/
# or use "goutte"
default_session: symfony
javascript_session: selenium2
browser_name: chrome
symfony: ~
selenium2: ~
Make your context files extend Behat\MinkExtension\Context\MinkContext
:
use Behat\MinkExtension\Context\MinkContext;
final class DemoContext extends MinkContext
{
// ...
}
Now we are ready to make some real queries to our website. Do it!
Open features/demo.feature
and add a new scenario:
Feature:
# ...
Scenario: I can navigate to the homepage
When I am on the homepage
Then the response status code should be 200
Try it with:
./vendor/bin/behat
Hey! Where is our browser? Add one more scenario to features/demo.feature
,
but this time add @javascript
above it:
Feature:
# ...
@javascript
Scenario: I can open the homepage in the Browser
When I am on the homepage
Then I should see a "body" element
Try it again:
./vendor/bin/behat
And... celebrate with a green pass mark on all tests!
If you have any issues, feel free to ask us in the comments below or anywhere on the Behat tutorial. We think Behat and that tutorial are great... as long as you can get it installed.
That's all folks!
12 Comments
Hey Easwaran,
Those steps come from the Mink context - some predefined steps that you can already use without creating your own custom steps. :)
Btw, if you hover over the step, hold Cmd and click on it - it will open the corresponding step definition. But you may need to install some Behat-related plugins in your PhpStorm first. I installed them and it works for me now :)
Cheers!
For anyone facing problems in using latest Selenium server and need the exact Selenium Server Standalone JAR used in this tutorial, you can download it from this link: Selenium Server Standalone 3.141.59
I switched to using Firefox instead of Chrome because the Chrome failed to work:
#behat.yml.dist
default:
suites:
default:
contexts:
- App\Tests\Behat\DemoContext
extensions:
FriendsOfBehat\SymfonyExtension:
bootstrap: tests/bootstrap.php
Behat\MinkExtension:
base_url: http://localhost:8000/
default_session: symfony
javascript_session: selenium2
browser_name: firefox
symfony: ~
selenium2: ~
Best regards,
Easwaran Chinraj
Hey Easwaran,
Thanks for sharing it with others! We're still using Chrome because it works for us, but we do have Selenium 3
Cheers!
Still works even with Symfony 6.4
I didn't managed to use it with
selenium-server-4.19.1.jar
so I start selenium server with
java -jar selenium-server-standalone-3.141.59.jar
or run it with docker
docker run -d -p 4444:4444 --name selenium-docker --shm-size=2g selenium/standalone-chrome:3.141.59
Hey Wojciech,
Thanks for confirming it works for your Symfony 6.4 app with Selenium server v3!
Cheers!
Hi,
when I do:
composer require friends-of-behat/mink-extension friends-of-behat/mink-browserkit-driver behat/mink-goutte-driver --dev
I don't get the recipe with the structure of files you say above...just no extra files.
I use PHP 7.4 - is that the root cause? Should I use PHP 8?
thanks!
Hey Dhpizza,
The problem should not be in PHP version... unless you got a message from Composer that something could not be installed because of the PHP legacy version you have. So, there should be a different problem most probably. Did you allow the Symfony Flex to execute those recipes? Because those are not official recipes, just contributed ones, and so you might have to allow Composer to execute them.
Cheers!
Thanks for mentioning robertfausk/behat-panther-extension :-) Let me know if you tried it🙃
Btw. there is a typo in:
„add @javasctipt above it“
Hey Robert Freigang
Thanks for reporting typo! I haven't tried this extension yet, but I have plans to do it =)
Cheers!
Dear SymfonyCasts,
I'm wondering where the step definitions are for the scenarios labeled
Scenario: I can navigate to the homepage
andScenario: I can open the homepage in the browser
. Even though the tests still passed. It's puzzling!Best regards,
Easwaran Chinraj