<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Kamil Kokot]]></title><description><![CDATA[Kamil Kokot]]></description><link>https://kamilkokot.com</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 02 Jan 2022 18:38:58 GMT</lastBuildDate><item><title><![CDATA[SymfonyExtension 2.1: Behat with Symfony 5]]></title><description><![CDATA[Friends of Behat’s SymfonyExtension becomes more and more popular as the downloads rose almost fivefold in the last year.
I’m happy to…]]></description><link>https://kamilkokot.com/symfony-extension-21-behat-with-symfony-5/</link><guid isPermaLink="false">https://kamilkokot.com/symfony-extension-21-behat-with-symfony-5/</guid><pubDate>Sun, 05 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension&quot;&gt;Friends of Behat’s SymfonyExtension&lt;/a&gt; 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.&lt;/p&gt;
&lt;p&gt;If you haven’t got to know it before, I’d recommend &lt;a href=&quot;https://kamilkokot.com/tame-behat-with-the-brand-new-symfony-extension/&quot;&gt;reading the last release announcement&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;symfony-5-and-php-74-support&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#symfony-5-and-php-74-support&quot; aria-label=&quot;symfony 5 and php 74 support permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Symfony 5 and PHP 7.4 support&lt;/h3&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;The mentioned packages are &lt;code class=&quot;language-text&quot;&gt;behat/mink&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;behat/mink-extension&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;behat/mink-browserkit-driver&lt;/code&gt;. To use the
forked versions, replace &lt;code class=&quot;language-text&quot;&gt;behat&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;friends-of-behat&lt;/code&gt; in their name, ending up with &lt;code class=&quot;language-text&quot;&gt;friends-of-behat/mink&lt;/code&gt;,
&lt;code class=&quot;language-text&quot;&gt;friends-of-behat/mink-extension&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;friends-of-behat/mink-browserkit-driver&lt;/code&gt; respectively.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Learn more: &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/pull/100&quot;&gt;Symfony 5&lt;/a&gt;, &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/pull/107&quot;&gt;PHP 7.4&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;minks-driver-service-container-exposed&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#minks-driver-service-container-exposed&quot; aria-label=&quot;minks driver service container exposed permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Mink’s driver service container exposed&lt;/h3&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;Starting from SymfonyExtension 2.1, you only need to inject &lt;code class=&quot;language-text&quot;&gt;behat.driver.service_container&lt;/code&gt; service or ask for
&lt;code class=&quot;language-text&quot;&gt;ContainerInterface $driverContainer&lt;/code&gt; to get access to your services within the tested application, both private and public.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SomeContext&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/** @var Session */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$minkSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;/** @var ContainerInterface */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$driverContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Session &lt;span class=&quot;token variable&quot;&gt;$minkSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ContainerInterface &lt;span class=&quot;token variable&quot;&gt;$driverContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;minkSession&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$minkSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;driverContainer&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$driverContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/** @When I visit the page :page */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;visitPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string &lt;span class=&quot;token variable&quot;&gt;$page&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; void
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;minkSession&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$page&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/** @Then the counter service should return :number */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;counterServiceShouldReturn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;int &lt;span class=&quot;token variable&quot;&gt;$number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; void
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$number&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;driverContainer&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;App\Counter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getCount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Learn more: &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/pull/116&quot;&gt;Driver service container exposed&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;simple-browserkit-integration&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#simple-browserkit-integration&quot; aria-label=&quot;simple browserkit integration permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Simple BrowserKit integration&lt;/h3&gt;
&lt;p&gt;If you don’t need Mink’s flexibility, the latest release contains a simple integration with BrowserKit. Whenever you
require &lt;code class=&quot;language-text&quot;&gt;Symfony\Bundle\FrameworkBundle\KernelBrowser&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;Symfony\Component\HttpKernel\HttpKernelBrowser&lt;/code&gt; in your context,
it’ll be autowired to &lt;code class=&quot;language-text&quot;&gt;test.client&lt;/code&gt; service.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SomeContext&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Context&lt;/span&gt; 
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/** @var KernelBrowser */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$browser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;KernelBrowser &lt;span class=&quot;token variable&quot;&gt;$browser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;browser&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$browser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/** @When I visit the page :page */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;visitPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string &lt;span class=&quot;token variable&quot;&gt;$page&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; void
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;browser&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$page&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Learn more: &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/pull/82&quot;&gt;BrowserKit integration&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;mink-service-exposed&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#mink-service-exposed&quot; aria-label=&quot;mink service exposed permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Mink service exposed&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SomeContext&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Context&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/** @var Mink */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$mink&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Mink &lt;span class=&quot;token variable&quot;&gt;$mink&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;mink&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$mink&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/** @When I visit the page :page */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;visitPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string &lt;span class=&quot;token variable&quot;&gt;$page&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; void
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;mink&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$page&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Learn more: &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/pull/69&quot;&gt;Mink&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;fobs-pageobjectextension-integration&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#fobs-pageobjectextension-integration&quot; aria-label=&quot;fobs pageobjectextension integration permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;FOB’s PageObjectExtension integration&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/FriendsOfBehat/PageObjectExtension&quot;&gt;Friends of Behat’s PageObjectExtension&lt;/a&gt; is a Behat extension inspired by &lt;a href=&quot;https://github.com/sensiolabs/BehatPageObjectExtension&quot;&gt;SensioLabs’ PageObjectExtension&lt;/a&gt;,
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.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LoginContext&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Context&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/** @var LoginPageInterface */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$loginPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__construct&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LoginPageInterface &lt;span class=&quot;token variable&quot;&gt;$loginPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;loginPage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$loginPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/** @When I log in as :username */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iWantToLogIn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string &lt;span class=&quot;token variable&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; void
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;loginPage&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;loginPage&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;password&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Learn more: &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/pull/105&quot;&gt;FOB’s PageObjectExtension&lt;/a&gt;, &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/issues/99&quot;&gt;SensionLabs’ PageObjectExtension&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;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. &lt;/p&gt;
&lt;p&gt;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! &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Seven Commands to Bulletproof Your Symfony Application CI Build]]></title><description><![CDATA[Over the course of years, I noticed there are more and more checks that are usually performed in our Symfony applications’
CI environment…]]></description><link>https://kamilkokot.com/seven-commands-to-bulletproof-your-symfony-application-ci-build/</link><guid isPermaLink="false">https://kamilkokot.com/seven-commands-to-bulletproof-your-symfony-application-ci-build/</guid><pubDate>Sun, 12 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Over the course of years, I noticed there are more and more checks that are usually performed in our Symfony applications’
CI environment. This is my attempt at writing down the most useful ones.&lt;/p&gt;
&lt;p&gt;Table of contents:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#1-checking-for-security-vulnerabilities&quot;&gt;Checking for security vulnerabilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-validating-package-configuration&quot;&gt;Validating package configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-linting-symfony-container&quot;&gt;Linting Symfony container&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-linting-twig-templates&quot;&gt;Linting Twig templates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-linting-yaml-files&quot;&gt;Linting YAML files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-testing-doctrine-migrations&quot;&gt;Testing Doctrine migrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-validating-doctrine-mappings&quot;&gt;Validating Doctrine mappings&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;1-checking-for-security-vulnerabilities&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-checking-for-security-vulnerabilities&quot; aria-label=&quot;1 checking for security vulnerabilities permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. Checking for security vulnerabilities&lt;/h3&gt;
&lt;p&gt;Security should be the most critical concern while developing any application. It should come as no surprise that there are
multiple solutions for ensuring that our application does not rely on dependencies with known vulnerabilities.
Although they differ in usage, they are all based on the same source - &lt;a href=&quot;https://github.com/FriendsOfPHP/security-advisories&quot;&gt;FriendsOfPHP/security-advisories&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&quot;symfony-cli&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#symfony-cli&quot; aria-label=&quot;symfony cli permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Symfony CLI&lt;/h4&gt;
&lt;p&gt;It is provided together with &lt;a href=&quot;https://symfony.com/download&quot;&gt;the Symfony binary&lt;/a&gt;, which is a recommended way to create new Symfony projects and includes
a convenient local web server, which comes handy during development. &lt;/p&gt;
&lt;p&gt;If you already use it as a web server in your CI build, I would recommend using it also for security checks.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;symfony security:check&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you do not have it in your CI build yet, the following &lt;code class=&quot;language-text&quot;&gt;.travis.yml&lt;/code&gt; configuration does the job:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;directories&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ~/.symfony

&lt;span class=&quot;token key atrule&quot;&gt;before_install&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token scalar string&quot;&gt;
        if [ ! -f ~/.symfony/bin/symfony ]; then
            wget https://get.symfony.com/cli/installer -O - | bash
        fi&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ~/.symfony/bin/symfony security&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;check&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;sensiolabs-security-checker&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#sensiolabs-security-checker&quot; aria-label=&quot;sensiolabs security checker permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;SensioLabs Security Checker&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/sensiolabs/security-checker&quot;&gt;SensioLabs/SecurityChecker&lt;/a&gt; is what I’ve been using before switching to Symfony CLI. It uses &lt;code class=&quot;language-text&quot;&gt;security.symfony.com&lt;/code&gt; API
to perform the check, which means your &lt;code class=&quot;language-text&quot;&gt;composer.lock&lt;/code&gt; will be uploaded there.&lt;/p&gt;
&lt;p&gt;To use it, add &lt;code class=&quot;language-text&quot;&gt;sensiolabs/security-checker&lt;/code&gt; to your &lt;code class=&quot;language-text&quot;&gt;require-dev&lt;/code&gt; section in &lt;code class=&quot;language-text&quot;&gt;composer.json&lt;/code&gt; and then run the following command:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;vendor/bin/security-checker security:check&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;roave-security-advisories&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#roave-security-advisories&quot; aria-label=&quot;roave security advisories permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Roave Security Advisories&lt;/h4&gt;
&lt;p&gt;While the previous two tools work in a similar way, &lt;a href=&quot;https://github.com/Roave/SecurityAdvisories&quot;&gt;Roave/SecurityAdvisories&lt;/a&gt; takes a different approach.&lt;/p&gt;
&lt;p&gt;It is a Composer package which defines vulnerable packages as its conflicts, preventing them from being installed and resulting in irresolvable dependencies.
This behaviour is a double-edged sword - it does not trigger when packages dependencies are installed from the lock file.&lt;/p&gt;
&lt;p&gt;My recommendation is to require this package only in the CI build:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;composer &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;
composer require --dev roave/security-advisories&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, resolving dependencies in complex projects takes a lot of time, which makes me prefer the other solutions.&lt;/p&gt;
&lt;h3 id=&quot;2-validating-package-configuration&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-validating-package-configuration&quot; aria-label=&quot;2 validating package configuration permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. Validating package configuration&lt;/h3&gt;
&lt;p&gt;Composer provides a command to validate your &lt;code class=&quot;language-text&quot;&gt;composer.json&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;composer.lock&lt;/code&gt; files. It checks whether your lock file
is up-to-date, whether used constraints are not too loose or too strict and whether the package is valid to be published on Packagist.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;composer validate --strict&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are a few switches available for this command:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;--strict&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Makes the command return non-zero code for warnings as well as errors.
For example, having overly strict dependency (&lt;code class=&quot;language-text&quot;&gt;1.0.0&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;^1.0&lt;/code&gt;) in &lt;code class=&quot;language-text&quot;&gt;require&lt;/code&gt; section will trigger a warning.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;--no-check-all&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Disables checking for overly strict or unbound dependencies in &lt;code class=&quot;language-text&quot;&gt;require&lt;/code&gt; section.
Even without this switch, it does not check the dependencies defined in &lt;code class=&quot;language-text&quot;&gt;require-dev&lt;/code&gt; section.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;--no-check-lock&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Disables checking whether the lock file is up-to-date.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;--no-check-publish&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ignores errors which prevent the package from be published on Packagist. Useful for internal applications that will
not be published, but required for open source packages.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I would recommend you starting with the most strict check and ignoring some parts later if needed.&lt;/p&gt;
&lt;h3 id=&quot;3-linting-symfony-container&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-linting-symfony-container&quot; aria-label=&quot;3 linting symfony container permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Linting Symfony container&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://symfony.com/blog/new-in-symfony-4-4-service-container-linter&quot;&gt;Introduced with Symfony 4.4&lt;/a&gt;, linting the container might help in finding dead services configurations.
We found &lt;a href=&quot;https://github.com/Sylius/Sylius/pull/10926&quot;&gt;a few in Sylius&lt;/a&gt; and decided to add it to the build to prevent us from introducing them anymore.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;bin/console lint:container&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;4-linting-twig-templates&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-linting-twig-templates&quot; aria-label=&quot;4 linting twig templates permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Linting Twig templates&lt;/h3&gt;
&lt;p&gt;Linting your Twig templates checks their syntax and might detect unused templates if an unexisting filter or function is used in those.
&lt;a href=&quot;https://github.com/Sylius/Sylius/pull/8056&quot;&gt;After running it on Sylius codebase&lt;/a&gt;, it has found a template calling parent blocks while not extending any template itself
and another template calling an unexisting filter.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;bin/console lint:twig templates&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Starting from Symfony 4.4, this command also includes a way to report usages of deprecated Twig features. It helped greatly with &lt;a href=&quot;https://github.com/Sylius/Sylius/pull/10955&quot;&gt;the upgrade
to Twig 3&lt;/a&gt;. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;bin/console lint:twig templates--show-deprecations&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I would not recommend adding deprecation checks to your CI build as it would make it more unstable - any deprecation in next Twig version would make it fail.&lt;/p&gt;
&lt;h3 id=&quot;5-linting-yaml-files&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-linting-yaml-files&quot; aria-label=&quot;5 linting yaml files permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. Linting YAML files&lt;/h3&gt;
&lt;p&gt;It is easy to make errors writing YAML files compared to XML. Therefore, it is essential to get feedback on those as fast as possible.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;bin/console lint:yaml config src translations&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;6-testing-doctrine-migrations&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-testing-doctrine-migrations&quot; aria-label=&quot;6 testing doctrine migrations permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Testing Doctrine migrations&lt;/h3&gt;
&lt;p&gt;If you provide Doctrine migrations in your application, it is desirable to test them. Most applications include the following
line in their CI builds:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;bin/console doctrine:migrations:migrate --no-interaction&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While this covers the most common path, it does not test reverting these migrations.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;bin/console doctrine:migrations:migrate --no-interaction
bin/console doctrine:migrations:migrate first --no-interaction
bin/console doctrine:migrations:migrate --no-interaction&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These three commands will first create the schema in the database, then revert the changes and create it once again.&lt;/p&gt;
&lt;h3 id=&quot;7-validating-doctrine-mappings&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-validating-doctrine-mappings&quot; aria-label=&quot;7 validating doctrine mappings permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. Validating Doctrine mappings&lt;/h3&gt;
&lt;p&gt;After the migrations have been run or the database schema has been synchronised in any other way, it’s worth to validate
your Doctrine mappings and whether they’re correctly synchronised with the database schema. &lt;/p&gt;
&lt;p&gt;It can be done with the following command:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;bin/console doctrine:schema:validate&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Surely, this list is non-exhaustive: it completely misses static analysers, testing frameworks, coding standard fixers and automation tools,
which I would like to include in another blog post in this series.&lt;/p&gt;
&lt;p&gt;What it mainly focuses on are commands that can be added with little effort but might be often overlooked. If you use one of those,
but it wasn’t mentioned above, let me know in the comments!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Tame Behat with the Brand New Symfony Extension]]></title><description><![CDATA[Over two years after the first release of this Friends of Behat’s Symfony Extension, I’m happy to announce
the availability of the second…]]></description><link>https://kamilkokot.com/tame-behat-with-the-brand-new-symfony-extension/</link><guid isPermaLink="false">https://kamilkokot.com/tame-behat-with-the-brand-new-symfony-extension/</guid><pubDate>Mon, 11 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Over two years after the first release of this &lt;a href=&quot;https://github.com/FriendsOfBehat&quot;&gt;Friends of Behat&lt;/a&gt;’s &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension&quot;&gt;Symfony Extension&lt;/a&gt;, I’m happy to announce
the availability of the second major version and write more about it.&lt;/p&gt;
&lt;p&gt;It is the already battle-tested solution with &lt;a href=&quot;https://github.com/Sylius/Sylius/pull/10102&quot;&gt;Sylius&lt;/a&gt; on 1300+ scenarios containing 14000+ steps, getting
traction in projects like &lt;a href=&quot;https://github.com/akeneo/pim-community-dev/pull/9416&quot;&gt;Akeneo&lt;/a&gt; or &lt;a href=&quot;https://github.com/Monofony/SymfonyStarter/pull/103&quot;&gt;Monofony&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;The mission behind it is to simplify the process of implementing &lt;a href=&quot;http://behat.org/en/latest/&quot;&gt;Behat&lt;/a&gt; contexts so that you can focus on the communication
with stakeholders and writing down business features instead of figuring out low-level testing infrastructure details.&lt;/p&gt;
&lt;h3 id=&quot;tldr&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#tldr&quot; aria-label=&quot;tldr permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;TL;DR&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Support for Symfony’s autowiring and autoconfiguration&lt;/li&gt;
&lt;li&gt;Symfony Flex contrib recipe to make installation easier&lt;/li&gt;
&lt;li&gt;Zero-configuration for most Symfony 3 and 4 based apps&lt;/li&gt;
&lt;li&gt;Unified application configuration and dotenv file handling (similar to the PHPUnit one)&lt;/li&gt;
&lt;li&gt;Integration with Mink, available out of the box&lt;/li&gt;
&lt;li&gt;Simplified usage, reduced the number of extensions from three to one&lt;/li&gt;
&lt;li&gt;Improved developer experience with more descriptive exceptions and more predictable overall behaviour&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to try it first, &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension#documentation&quot;&gt;dive straight into the documentation&lt;/a&gt;. &lt;/p&gt;
&lt;h3 id=&quot;support-for-symfonys-autowiring-and-autoconfiguration&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#support-for-symfonys-autowiring-and-autoconfiguration&quot; aria-label=&quot;support for symfonys autowiring and autoconfiguration permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Support for Symfony’s autowiring and autoconfiguration&lt;/h3&gt;
&lt;p&gt;Ever since I have started working with Behat and Symfony on more complex projects, the number of configuration changes
needed to implement even simple steps was an issue and it was going worse and worse.&lt;/p&gt;
&lt;p&gt;Whether it was &lt;code class=&quot;language-text&quot;&gt;Behat/Symfony2Extension&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;FriendsOfBehat/SymfonyExtension&lt;/code&gt;, injecting a dependency into
a context required too much hassle and pulled me away from the domain being modelled.&lt;/p&gt;
&lt;p&gt;The common use case is to have a context which implements a step like &lt;code class=&quot;language-text&quot;&gt;Given I am a logged in customer&lt;/code&gt; that is used in
every suite which does web acceptance testing.&lt;/p&gt;
&lt;p&gt;Let’s assume we need two Behat suites using the same context depending on &lt;code class=&quot;language-text&quot;&gt;kernel&lt;/code&gt; service and compare the required
configuration for every Symfony extension for Behat out there.&lt;/p&gt;
&lt;h4 id=&quot;behatsymfony2extension&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#behatsymfony2extension&quot; aria-label=&quot;behatsymfony2extension permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Behat/Symfony2Extension&lt;/h4&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# behat.yml&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;first_suite&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token key atrule&quot;&gt;contexts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;FeatureContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token key atrule&quot;&gt;kernel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@kernel&apos;&lt;/span&gt;&lt;/span&gt;            
&lt;span class=&quot;token key atrule&quot;&gt;second_suite&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token key atrule&quot;&gt;contexts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;FeatureContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token key atrule&quot;&gt;kernel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@kernel&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This snippet does not look that bad, mostly because of its size. It gets longer and longer with every new dependency or suite though.
Adding a new dependency to a context requires changing the configuration of every suite.&lt;/p&gt;
&lt;h4 id=&quot;friendsofbehatsymfonyextension-v1&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#friendsofbehatsymfonyextension-v1&quot; aria-label=&quot;friendsofbehatsymfonyextension v1 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;FriendsOfBehat/SymfonyExtension v1&lt;/h4&gt;
&lt;p&gt;Finding all places where a context is used and modifying its dependencies is a boring work, which I wanted to avoid in
the first version of &lt;abbr title=&quot;Friends Of Behat&quot;&gt;FOB&lt;/abbr&gt;’s SymfonyExtension. &lt;/p&gt;
&lt;p&gt;It was possible by registering contexts as services, which fundamentally changes the way you use them in Behat.
This is why I decided to write my own extension to integrate Behat with Symfony.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# behat.yml&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;first_suite&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token key atrule&quot;&gt;contexts_services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FeatureContext&lt;/span&gt;            
&lt;span class=&quot;token key atrule&quot;&gt;second_suite&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token key atrule&quot;&gt;contexts_services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; FeatureContext&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Symfony services file loaded by the extension&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;FeatureContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@__symfony__.kernel&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token key atrule&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;fob.context_service&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The duplication is removed, but it has introduced more boilerplate code and own conventions which are hard to get at first:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;__symfony__&lt;/code&gt; prefix when referencing service from Symfony application container prevented autocomplete in IDEs
from working correctly&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;fob.context_service&lt;/code&gt; tag was required by the internal infrastructure to be able to use a service as a context, but
it caused bugs quite often as it was so easy to forget it&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;contexts_services&lt;/code&gt; instead of default &lt;code class=&quot;language-text&quot;&gt;contexts&lt;/code&gt; has not introduced any measurable benefit, it was supposed to prevent
conflicts with the default configuration if one does not use context services in every suite&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The whole process of registering contexts manually was far from pleasant.&lt;/p&gt;
&lt;h4 id=&quot;friendsofbehatsymfonyextension-v2&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#friendsofbehatsymfonyextension-v2&quot; aria-label=&quot;friendsofbehatsymfonyextension v2 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;FriendsOfBehat/SymfonyExtension v2&lt;/h4&gt;
&lt;p&gt;The newest version reduces required boilerplate code by incorporating autowiring and autoconfiguration as first-class
mechanisms and sticking to the already known conventions.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# behat.yml&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;first_suite&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token key atrule&quot;&gt;contexts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; App\Tests\Behat\FeatureContext&lt;/span&gt;            
&lt;span class=&quot;token key atrule&quot;&gt;second_suite&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token key atrule&quot;&gt;contexts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; App\Tests\Behat\FeatureContext&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If your context constructor has kernel argument type-hinted, this is all you need to make it work. &lt;/p&gt;
&lt;p&gt;No need to worry about duplicated configuration, weird conventions, tagging contexts or using prefixes when referring to services.
And you can inject private services as well! &lt;/p&gt;
&lt;p&gt;The extension provides a dependency injection configuration which automatically finds your contexts and autowires them:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# config/services_test.yaml&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;_defaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;autowire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;autoconfigure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;

    &lt;span class=&quot;token key atrule&quot;&gt;App\Tests\Behat\&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../tests/Behat/*&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The following file is loaded only in the test environment. Your production and development environments are not
affected with any performance loss. However, if you prefer not to rely on autowiring, you can define the context as a
service on your own - remember to make it public though:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# config/services_test.yaml&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;App\Tests\Behat\FeatureContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@kernel&apos;&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;symfony-flex-recipe&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#symfony-flex-recipe&quot; aria-label=&quot;symfony flex recipe permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Symfony Flex recipe&lt;/h3&gt;
&lt;p&gt;If you use &lt;a href=&quot;https://symfony.com/doc/current/setup/flex.html&quot;&gt;Symfony Flex&lt;/a&gt; to manage your Symfony application, installation and configuration of the extension could not be easier.&lt;/p&gt;
&lt;p&gt;All you need to do is to install the extension and agree for installing a contrib recipe for it:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;composer &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; friends-of-behat/symfony-extension:^2.0 --dev
composer &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; behat&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In less than a minute you have a working setup of Behat with SymfonyExtension and you are ready to write your features.&lt;/p&gt;
&lt;p&gt;If you do not use Symfony Flex, &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/blob/master/docs/01_installation.md#installation&quot;&gt;follow the installation documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;zero-configuration-for-most-symfony-3-and-4-based-apps&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#zero-configuration-for-most-symfony-3-and-4-based-apps&quot; aria-label=&quot;zero configuration for most symfony 3 and 4 based apps permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Zero-configuration for most Symfony 3 and 4 based apps&lt;/h3&gt;
&lt;p&gt;Whether you use Symfony 3 or Symfony 4, the new extension got you covered. &lt;/p&gt;
&lt;p&gt;It will try to guess the sensible default configuration and in most cases, you will not need to write any more configuration than
the following (assuming Flex have not done it for you):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# behat.yml&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;extensions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;FriendsOfBehat\SymfonyExtension&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token null important&quot;&gt;~&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/blob/master/docs/05_configuration_reference.md#configuration-reference&quot;&gt;Learn more about the default settings&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;mink-integration&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#mink-integration&quot; aria-label=&quot;mink integration permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Mink integration&lt;/h3&gt;
&lt;p&gt;This extension provides a driver for &lt;a href=&quot;http://mink.behat.org/en/latest/&quot;&gt;Mink&lt;/a&gt; based on BrowserKit called &lt;code class=&quot;language-text&quot;&gt;symfony&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;If you switch from &lt;code class=&quot;language-text&quot;&gt;Behat\Symfony2Extension&lt;/code&gt;, the behaviour stays mostly the same.
There is only one minor implementation detail that is worth to know.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;symfony2&lt;/code&gt; driver from the former extension uses the same kernel for both fetching application services and handling
requests. This might lead to unexpected results if your code is not idempotent and relies on services state.&lt;/p&gt;
&lt;p&gt;Given the following scenario and its implementation:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;gherkin&quot;&gt;&lt;pre class=&quot;language-gherkin&quot;&gt;&lt;code class=&quot;language-gherkin&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Please do not write scenarios like this&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# It is just for demonstration purposes&lt;/span&gt;
Given the service state is set to 42
Then I should get 42 from the API
And I should get 42 from the API&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token shell-comment comment&quot;&gt;# Context implementation&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;/**
 * @Given the service state is set to :state
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;serviceStateIs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string &lt;span class=&quot;token variable&quot;&gt;$state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; void
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/**
 * @Then I should get :state from the API
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;iShouldGetFromAPI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;string &lt;span class=&quot;token variable&quot;&gt;$state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; void
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;minkSession&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;visit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token single-quoted-string string&quot;&gt;&apos;/api/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;assert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$state&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;minkSession&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;php&quot;&gt;&lt;pre class=&quot;language-php&quot;&gt;&lt;code class=&quot;language-php&quot;&gt;&lt;span class=&quot;token shell-comment comment&quot;&gt;# Symfony controller&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;__invoke&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Response
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This scenario would fail on the second &lt;code class=&quot;language-text&quot;&gt;Then&lt;/code&gt; step when using &lt;code class=&quot;language-text&quot;&gt;Behat\Symfony2Extension&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It happens because the kernel is rebooted after each request, so that the first &lt;code class=&quot;language-text&quot;&gt;Then&lt;/code&gt; step one uses the same container that is
used in Behat &lt;code class=&quot;language-text&quot;&gt;Given&lt;/code&gt; step before, but the second &lt;code class=&quot;language-text&quot;&gt;Then&lt;/code&gt; step uses a rebooted container which does not share the same state.
This might make your tests fragile, eg. when you change assertions order.&lt;/p&gt;
&lt;p&gt;When run with &lt;code class=&quot;language-text&quot;&gt;FriendsOfBehat\SymfonyExtension&lt;/code&gt;, the scenario would fail on the first &lt;code class=&quot;language-text&quot;&gt;Then&lt;/code&gt; step because the service
state is not shared between Behat and HTTP application.&lt;/p&gt;
&lt;p&gt;If you want to learn more, check out &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/blob/master/docs/04_bs2e_differences.md#differences-from-behatsymfony2extension&quot;&gt;the documentation about differences between Symfony extensions&lt;/a&gt;
or &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/blob/master/docs/03_mink_integration.md#mink-integration&quot;&gt;the documenation about Mink integration&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;whats-next&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#whats-next&quot; aria-label=&quot;whats next permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;What’s next?&lt;/h3&gt;
&lt;p&gt;With all those new, shiny features mentioned above, there are still a few ideas in my mind that would be great to see in the future:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/issues/61&quot;&gt;providing Mink as a service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/issues/62&quot;&gt;autowiring and autoconfiguration for steps definitions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/issues/67&quot;&gt;exposing BrowserKit API as complementary to Mink API (with Panther support)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I made a GitHub project which is used as a &lt;a href=&quot;https://github.com/FriendsOfBehat/SymfonyExtension/projects/1&quot;&gt;roadmap&lt;/a&gt; for this project.&lt;/p&gt;</content:encoded></item></channel></rss>