Unit testing is not the only practice software engineers should use to ensure a project is operating correctly. Behavior-driven development has been growing in popularity since 2008. In short, BDD starts with a “story.” Whoever is in charge of designing the software’s flow writes use-cases for features in human-readable language. Tests are then run using headless browsers and other automation tools to ensure the story can be execute properly.
A short story in Gherkin, Behat’s markup language, might look like this:
Scenario: Search for red hat Given I am on "/search"And I fill in "search_input" with "red hat"And press "submit"Then I should see "red hat - The best clothing item you will ever buy."
This story looks eerily similar to a functional requirements document because, well, that’s what it is. Typically someone doing quality assurance would have to manually follow this scenario every time a new feature or bug fix has been implemented in order to properly regression test. But Behat can automatically test these scenario in a variety of browsers, headless or not. This is great for testing complex features like those involving AJAX requests. Mink defines how Behat should translate the Gherkin steps into browser commands in order to test the site. We can also define our own custom steps here.
Let’s take a look at how we can implement Behat to test an e-commerce site.
Clone the simple e-commerce site and checkout the shop-basic tag. This post assumes you are working in either OSX or Linux.
git clone https://github.com/nater1067/Shop-Top.git
git checkout -b shop-basic
curl -sS https://getcomposer.org/installer | php
php composer.phar install
Press enter after the composer install for each field to keep default values. Now you should be able to navigate to http://127.0.0.1:8080/search to see a working ecommerce site. Try buying a red hat to see how the site works. (Note: You will not be charged for the any red hats on this site.)
Including Behat and Mink Libraries
We need to add a few dependencies to our project using composer. This took a little time to figure out, and at the time of writing this post works. However be warned - you may need to adjust the version numbers in order to get this working in the future.
Run composer update to download the the Behat and Mink libraries. Then create the necessary Behat files.
php composer.phar update
This creates a new directory, “features”, which holds our Gherkin and Behat FeatureContext. Modify the FeatureContext to extend MinkContext. This allows us to leverage the pre-defined steps included in Mink.
Time to write our features in human terms. Create two new files: features/search.feature and features/buy.feature.
# features/search.featureFeature: Clothes Search In order to search for clothes As a shopper I need to enter a search query and press submitScenario: Search for red hat Given I am on "/search"And I fill in "search_input" with "red hat"And press "submit"Then I should see "red hat - The best clothing item you will ever buy."Scenario: Search for empty string Given I am on "/search"And press "submit"Then I should not see "Results"
# features/buy.featureFeature: Buy Clothing Item In order to buy a clothing item As a shopper I need to press buy next to an itemScenario: Buy red hat Given I am on "/search"And I fill in "search_input" with "red hat"And I press "submit"Then I press "buy_redhat"Then I should see "You purchased 1 red hat!"
These files describe, in fairly simple terms, what the application should do. We should be able to search for a red hat, and see the description in the results.
Now that we have created a couple of Gherkin stories, we can run Behat to test our site’s behavior in a headless browser.
Behat is now using a headless browser to confirm whether our app adheres to the steps we’ve defined in the .feature files. We should see our stories outputted to the terminal. If everything works we should see a lot of green, and a summary of successful scenarios and steps.
Now that you’ve got Behat running successfully within a Symfony 2 application, it’s time to get your hands dirty with more advanced test behavior-driven development. You’ve seen very simple examples of Behat tests, but Behat can do so much more than check simple forms. Try adding bundle-specific features with the Symfony 2 Behat bundle. Add some tests which check front-end functionality such as AJAX features. Tons of information can be found in the Behat docs at http://docs.behat.org .
Have an improvement for this post? What additional Behat functionality would you like included in this post? Please comment below.
After installing you should see a little fox somewhere on your browser. Click that fox.
Make sure “Use proxies based on their pre-defined patterns and priorities” is selected.
Click on the new fox and select “Options”. Add a new proxy for 127.0.0.1 port 8080.
Then add a new url pattern. Set “symfony.dev” as the url pattern, optionally set a pattern name, make sure whitelist urls and wildcards are selected. Press save, exit foxy proxy and navigate to http://symfony.dev.
For the purpose of this tutorial there are only a few things you need to know about Vagrant and Puppet. Vagrant creates virtual machines using a number of different providers. We’ll be using Virtualbox. Vagrant runs Puppet for you on the newly created virtual machine. Puppet handles the installation of various dependencies. (Think Apache, mysql, curl, etc.) This process is known as provisioning.
Why encapsulate development environments with Vagrant?
When we use Vagrant to create new virtual development environments we avoid the very real possibility that we could mess up our personal development machines. People have used virtual machines for development for years. The drawbacks of passing around USB sticks with Virtualbox images are easy to spot. For one, without a complicated and slow shared folder setup, you need to use and IDE or text editor inside the VM to modify code. You won’t be able to run this environment headless to free up clock cycles on your host machine. Managing installed applications across a teams VMs is a pain. Why not just include a Vagrantfile and a few Puppet manifests instead? Instead of passing around a virtual machine a few gigabytes in size, just include your Vagrant and Puppet in a project’s source control. That’s it. In future tutorials we will be using the environment we create here to start a new virtual machine running Symfony 2 with the above command. See vagrantup.com for more reasons why Vagrant is awesome.
Create a Symfony Project with Composer
Let’s have Composer install a Symfony 2 project in a directory, let’s call the directory symfony2. Open up a terminal window and enter the following commands:
While we are in the new Symfony project, let’s disable some security checks in the app_dev.php file. Comment out the following lines:
# /web/app_dev.php// header('HTTP/1.0 403 Forbidden');// exit('You are not allowed to access this file. Check '.basename(FILE).' for more information.');
We have Symfony 2, but we’re not going to be able to develop in this awesome framework until it’s running on Apache. Let’s have Vagrant do the heavy-lifting for this.
Setting up Vagrant
Vagrant is powerful out of the box, and there’s not a whole lot of configuration we have to do ourselves. Make sure you have the latest version of Vagrant installed. See http://www.vagrantup.com/downloads.html for installation packages. Open the project directory in another terminal.
vagrant init hashicorp/precise32
Then open up the newly created Vagrantfile in your favorite text editor (use PHPStorm!) and enable Puppet provisioning. Also, ensure port 8080 is forwarded to 80 on the VM. Vagrant is now ready to go.
# /VagrantfileVAGRANTFILE_API_VERSION="2"Vagrant.configure(VAGRANTFILE_API_VERSION)do|config|config.vm.box="hashicorp/precise32"config.vm.network"forwarded_port",guest:80,host:8080# Enable provisioning with Puppet stand alone. Puppet manifests# are contained in a directory path relative to this Vagrantfile.# You will need to create the manifests directory and a manifest in# the file default.pp in the manifests_path directory.#config.vm.provision"puppet"do|puppet|puppet.manifests_path="manifests"puppet.manifest_file="site.pp"endend
Provisioning with Puppet / Symfony’s Requirements
Let’s face it.. Symfony 2 is amazing and all powerful, but not the fastest framework to get started with. Let’s eliminate the need for manual intervention when setting up a new symfony application. In order to get our symfony application running we need to ensure 3 things happen:
Install our dependencies
Since we are keeping this Puppet script very basic for now, all we need to to install Apache, php, modrewrite and mysql. Create a folder called manifests in our project and a file named sites.pp in the new folder.
Now run “vagrant up” from your project directory and watch as your Symfony 2 application comes to life! Navigate to http://127.0.0.1:8080 to see a Symfony 2 welcome page.
Now we have a working Symfony 2 project running on a virtual machine we can develop on immediately. To see the real beauty of having Vagrant and Puppet do the work for us, copy this project to another device, run “composer install” and then “vagrant up.” You should be able to develop on the project from any host running OSX, Windows or Linux and see your changes at http://127.0.0.1:8080 .