Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

BDD Features

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

I'm sure you've heard of "Test Driven Development" where you write the tests first, and you code until those tests pass. That process is really cool! But we're talking about "Behavior Driven Development" or BDD. This is the idea that you are going to write down the behavior of your application first and then develop it.

Behavior-Driven Development

This might sound pretty obvious to you: why would I code without thinking about what I'm going to code? But that actually happens pretty often.

Behat and BDD are going to give us a very specific path to follow so that we think first, and then we code. We do this to maximize business value. There are two types of BDD, story and spec. Without getting too far into the details of each, story BDD is done with Behat and usually ends up with functional tests. Spec BDD is handled by another wonderful tool called PHPSpec and this ends up focusing on unit testing, how you actually design your classes and functions. They're both cool and in a perfect world you'll use both.

One minute of theory:

With BDD we break down our development process into four steps:

  1. Define the business value of all of the big feature.
  2. Prioritize those so you work on the ones with the highest business value first.
  3. Take one feature and break it down into all of the different user stories or scenarios.
  4. Write the code for the feature, since you now know how you want it to behave.

To do all this planning, Behat uses a language called Gherkin. This isn't special to Behat or PHP, it also exists in Ruby, Java and every other programming world out there which is a good thing.

Writing Features

Our application is already partially built, but let's pretend that it isn't and we're just in the planning stages. First we know we'll need an authentication feature. So let's go into the features directory and create a new authentication.feature file. Each feature will have it's own file in here:

Feature: Authentication
In order to gain access to the site management area
As an admin
I need to be able to login and logout

We always start with the same header Feature and a short description of it. Here we'll just say "Authentication". The next three lines are very important. Our next line is always "In order to" followed by the business value. In the case of the Raptor Store, since you need to login to see the product area, I would say that the business value is "to gain access to the management area".

Next is "As a" and you say who is going to benefit from this feature, in our case it would be an admin user. And the third line is, "I need to be able to" followed by a short description of what the user would actually be able to do with this feature. In our store that is "login and logout".

The most important parts are the first two lines, the business value and the user - or role - that's going to benefit from this value. If either of these are difficult to define then maybe your feature isn't actually valuable. Or maybe none is benefiting from it. Perhaps move onto a different task.

Writing Good Business Values

Back in the Raptor store, login with admin/admin and check out the product admin area. Let's describe that! Back into the features directory and create a new product_admin.feature file. And we'll start the same as we always do:

Feature: Product admin panel
... lines 2 - 5

So why do we care about having a product admin area? It's not just so we can click links and fill out boxes. Nobody cares about that. The true reason to go in there is to control the products on the frontend. So let's say just that:

... line 1
In order to maintain the products shown on the site
As an admin
I need to be able to add/edit/delete products

Writing at the Tech Level of your User

That looks good. What else do we have? Check out the "Fence Security Activated" message on the site. Let's imagine we need to create an API where someone can make an API request to turn the fence security on or off from anywhere. For example, if you're running from dinosaurs somewhere, you might want to pull out your iphone and turn the fences back on.

We'll need another feature file called fence_api.feature. Start with:

Feature: Remote control fence API
... lines 2 - 5

The business value is pretty clear:

... line 1
In order to control fence security from anywhere
... lines 3 - 5

The user that benefits from this isn't some browser-using admin user: it's a more-advanced API user:

... lines 1 - 2
As an API user
I need to be able to POST JSON instructions that turn fences on/off

I feel safer already.

Bad Business Value

There's a common pitfall, and it looks like this:

... line 1
In order to add/edit/delete products
As an admin
I need to be able to add/edit/delete products

Notice the In order to and the I need to be able to lines are basically the same. This is a sign of a bad business value. Being able to add/edit/delete products is not a business value. People don't go into the product admin area just for the delight of adding, editing and deleting products. They go into the admin area because that allows them to control the products that are rendered on the front end.

This is subtle, but really important because when we build the admin area, it will focus our efforts: we know that we're building this just as a tool so that you can control things on the frontend. Which sadly for the developer means we maybe don't need that crazy drag-and-drop interface for adding videos from YouTube. Our admin user - who we're building this feature for - doesn't care about using it, and it might be too technical for them anyways.

Focus on your business value, and keep the feature at the technical level of who you're building it for.

Leave a comment!

Login or Register to join the conversation
mehdi Avatar

Hi there,
Can you clarify the last paragraph from " it will focus our
efforts ....." ? I read it many times but I don't get it.
I understand that in "In order to" we put the feature description from the user perspective and in " I need to be able to" we put the feature description from the developer perspective.


Hey mehdi!

Of course :).

I understand that in "In order to" we put the feature description from the user perspective and in " I need to be able to" we put the feature description from the developer perspective.

Yes, this is quite a good way of explaining it! So, in the last paragraph, here is what I'm trying to say. If your In order to is written well, then it will really explain the purpose of this feature: why we are building it, and how the user of this feature will benefit. This is important, because, as developers, it helps us think about the purpose of this feature. So, when I go to build the production admin area, instead of "focusing" on making forms and adding buttons, I'll be thinking about the feature from the user's perspective.

Let me give you a real example. If I am not thinking about how the user will actually use our new product admin area, then I might (as a developer) add a lot of extra features that aren't needed - maybe a cool upload widget, or a super fancy text editor. But, if I think about what the admin user actually wants to accomplish, I may realize that some of these features are not actually necessary or even wanted. I might instead think of other ways to improve/build the admin area that will actually help them with their business value. So, it "focuses" us on building the admin area in the correct way: build it for the user.

I hope this helps!


Default user avatar

Ah okay. This script is for the previous chapter's video and the previous chapter's script is for this video.


You're right - the videos were flipped! I've fixed that at sha: https://github.com/knpunive...



First challenge not working: "CodeMirror is not defined" in gherkin.js:25


Hey boykodev!

Thanks for informing us about that sneaky bug, we will fix it as soon as possible


1 Reply

Even after one year passed, it's still not working...:(
The message is different though, now it says:
"Your challenge machine shutdown! We do this after awhile for security reasons. Reload the page to get a fresh challenge."


Same for challenges 3.1 and 5

GDIBass Avatar
GDIBass Avatar GDIBass | posted 5 years ago

Really liking the challenges in this one!


Cool, keep it going!

1 Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial uses a very old version of Symfony. The fundamentals of Behat are still valid, but integration with Symfony will be different.

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "php": ">=5.4.0, <7.3.0",
        "symfony/symfony": "^2.7", // v2.7.4
        "twig/twig": "^1.22", // v1.22.1
        "sensio/framework-extra-bundle": "^3.0", // v3.0.16
        "doctrine/doctrine-bundle": "^1.5", // v1.5.1
        "doctrine/orm": "^2.5", // v2.5.1
        "doctrine/doctrine-fixtures-bundle": "^2.2", // v2.2.1
        "behat/symfony2-extension": "^2.0" // v2.0.0
    "require-dev": {
        "behat/mink-extension": "^2.0", // v2.0.1
        "behat/mink-goutte-driver": "^1.1", // v1.1.0
        "behat/mink-selenium2-driver": "^1.2", // v1.2.0
        "phpunit/phpunit": "^4.8" // 4.8.18