SymfonyExtension 2.1: Behat with Symfony 5
April 05, 2020 • 4 minutes read • 0 comments • Edit on GitHub
Friends of Behat’s SymfonyExtension becomes more and more popular as the downloads rose almost fivefold in the last year. I’m happy to announce the new release bringing support for Symfony 5 and PHP 7.4, together with functional improvements.
If you haven’t got to know it before, I’d recommend reading the last release announcement.
Symfony 5 and PHP 7.4 support
With Symfony 5 and PHP 7.4 released in late November 2019, adding support for it was only a matter of time. Behat officially started supporting those in early February 2020 and SymfonyExtension was ready for it shortly after.
Unfortunately, Mink ecosystem was lagging behind. Since most of the projects rely on both Behat and Mink, I’ve decided to fork those libraries to Friends of Behat organisation. This way, I could quickly release drop-in replacements for problematic libraries, having Symfony 5 support as my only objective - any other improvements or changes are currently not accepted.
The mentioned packages are behat/mink
, behat/mink-extension
and behat/mink-browserkit-driver
. To use the
forked versions, replace behat
with friends-of-behat
in their name, ending up with friends-of-behat/mink
,
friends-of-behat/mink-extension
and friends-of-behat/mink-browserkit-driver
respectively.
SymfonyExtension 2.1 removes support for Symfony 3.4, leaving Symfony ^4.4 and ^5.0 as the only supported versions. As for PHP, all versions between 7.1 and 7.4 are currently supported.
Learn more: Symfony 5, PHP 7.4.
Mink’s driver service container exposed
Raised multiple times in issues on the repository, the 2.0 release removed the possibility of getting into Mink’s driver service container easily. Getting it is especially helpful when you want to assert emails sent or messages dispatched during the last HTTP request.
Starting from SymfonyExtension 2.1, you only need to inject behat.driver.service_container
service or ask for
ContainerInterface $driverContainer
to get access to your services within the tested application, both private and public.
final class SomeContext implements Context {
/** @var Session */
private $minkSession;
/** @var ContainerInterface */
private $driverContainer;
public function __construct(Session $minkSession, ContainerInterface $driverContainer)
{
$this->minkSession = $minkSession;
$this->driverContainer = $driverContainer;
}
/** @When I visit the page :page */
public function visitPage(string $page): void
{
$this->minkSession->visit($page);
}
/** @Then the counter service should return :number */
public function counterServiceShouldReturn(int $number): void
{
assert($number === $this->driverContainer->get('App\Counter')->getCount());
}
}
Learn more: Driver service container exposed.
Simple BrowserKit integration
If you don’t need Mink’s flexibility, the latest release contains a simple integration with BrowserKit. Whenever you
require Symfony\Bundle\FrameworkBundle\KernelBrowser
or Symfony\Component\HttpKernel\HttpKernelBrowser
in your context,
it’ll be autowired to test.client
service.
final class SomeContext implements Context
{
/** @var KernelBrowser */
private $browser;
public function __construct(KernelBrowser $browser)
{
$this->browser = $browser;
}
/** @When I visit the page :page */
public function visitPage(string $page): void
{
$this->browser->request('GET', $page);
}
}
Learn more: BrowserKit integration.
Mink service exposed
As 2.0 has only supported exposing Mink’s default session, 2.1 brings more flexibility in that manner. It is possible to both inject and autowire the whole Mink service to your context now.
final class SomeContext implements Context
{
/** @var Mink */
private $mink;
public function __construct(Mink $mink)
{
$this->mink = $mink;
}
/** @When I visit the page :page */
public function visitPage(string $page): void
{
$this->mink->getSession()->visit($page);
}
}
Learn more: Mink.
FOB’s PageObjectExtension integration
Friends of Behat’s PageObjectExtension is a Behat extension inspired by SensioLabs’ PageObjectExtension, that is used by Sylius to abstract away pages and elements details from Behat contexts. Unfortunately, the latter could not be supported by SymfonyExtension, due to using Mink’s Element classes which breaks lazy-loading for Mink integration.
Within this integration, all the pages and elements are autowired and autoconfigured, which reduces the need to write boring infrastructure code. When in doubt, take a look at the feature file in SymfonyExtension or its usage in Sylius.
final class LoginContext implements Context
{
/** @var LoginPageInterface */
private $loginPage;
public function __construct(LoginPageInterface $loginPage)
{
$this->loginPage = $loginPage;
}
/** @When I log in as :username */
public function iWantToLogIn(string $username): void
{
$this->loginPage->open();
$this->loginPage->login($username, 'password');
}
}
Learn more: FOB’s PageObjectExtension, SensionLabs’ PageObjectExtension.
Conclusion
SymfonyExtension is on its way to surpass one million downloads in the next month. I’m pleased to create a library that is useful and removes friction when adopting BDD and automatizing scenarios.
As for the future developments, I’d like to replace Mink with a dedicated, Symfony-based alternative API. Publishing a tutorial on making use of BDD within Symfony 5 application context is also an interesting idea. Feel free to let me know what would you like to see first!
Subscribe to the newsletter
Stay up to date with my content. Opt-out at any time.I'm Kamil Kokot. My goal is to make software testing as effortless as possible so that you can develop with confidence. I maintain Behat and FriendsOfBehat libraries.
Eager to use @BehatPHP in your @symfony 5 application? The latest release of FriendsOfBehat's SymfonyExtension comes to the rescue! Symfony 5 and PHP 7.4 support, better Mink and BrowserKit integrations and a few more improvements included. https://t.co/yYRH9J2knh
— Kamil Kokot (@pamilme) April 5, 2020