Behat turns 2! Have fun and test what matters!

Published on

Jul 13, 2011

how2tips

Today we're thrilled to announce that Behat - the behavioral-driven-development framework written by our very own Konstantin - turns 2.0! The release is a huge evolution packed with new features, greatly updated documentation, improved exception messages and a brand new way to specify your definitions.

Already using Behat? Check out the migration guide.

Not already using Behat? Give me just 4 minutes to convince you! Seriously!

So, what is Behat?

Behat allows you to write human-readable sentences that are executed as tests. The idea is to focus on the actual features of your application, writing simple sentences that describe that feature. These simple sentences are then executed as tests.

Behat can be used to test anything (see the quick tour where we test the famous ls UNIX command), but in this post I'll show you its most powerful application: testing web applications.

For example, imagine you need to build a contact form. Before doing any coding, you'd create a contact_form.feature file - part of it might look like this:

Feature: Contacting developer
  In order to contact site developer
  As a visitor
  I need to be able to submit a contact form

  Scenario: Successfully submit the contact form
    Given I am on "/contact"
    When I fill in "Your name:" with "Ryan"
     And I fill in "Message:" with "Hi there!!!"
     And I select "general_question" from "Question type:"
     And I press "Contact"
    Then I should see "Your message has been sent!"

To "execute" this test, run the behat command-line utility:

$ behat features/contact_form.feature

When you run this command, each line of the scenario is actually executed within an HTTP client (e.g. a headless browser or a real browser like Firefox). In other words, that client goes to the /contact page, fills in some fields, clicks Contact, and checks some information.

But how is this possible? How does Behat know what to do with these meaningless sentences? There are two answers:

1) For each line of the feature (except for line Scenario line, which is ignored), Behat searches through a list of regular expressions (called definitions) until it finds one that matches the line. When it finds a matching definition, it executes some PHP code associated with it. This is Behat in a nutshell.

2) Behat partners with another library - Mink - which is a "browser emulation abstraction library" that comes with a long list of Behat definitions for common browser tasks.

Tip!! You do not need to write regular expressions to use Behat - I'll show you later how Behat will create any needed regex for you.

So, what is Mink?

In fancy terms, Mink is a "browser emulation abstraction library". In layman's terms, it's a PHP library that let's you talk to a "browser" via a common object oriented interface:

<?php

$mink->getSession()->visit('/contact');
$mink->getSession()->getPage()->fillField('Your name, please:', 'Ryan');
$items = $mink->getSession()->getPage()->findAll('css', 'li.items');

The beauty is that this code could be executed inside any "type" of browser. For example, this code could be executed in a "headless" browser (via Goutte) or in a real-life browser like Firefox (via Sahi)!

In other words, if you use Mink for your functional testing, you can execute the same test in any browser. That's awesome.

To make things worse, the API is beautiful.

Behat and Mink

Behat reads each line from a scenario, finds a definition whose regular expression matches that line, and then executes the PHP code in that definition.

Mink allows you to use an object-oriented interface to interact with any type of HTTP client (i.e. browser).

When you put Behat and Mink together, you have the ability to write short and clear sentences that are run as a test and executed inside a real browser.

By default, Mink will execute our earlier example in a headless browser. If everything passes, you'll see:

First successful scenario

To run the test using in a real browser like Firefox (using Sahi), just add @javascript before the scenario and run the tests again:

@javascript
Scenario: Successfully submit the contact form
  Given: I am on "/contact"
  # ...

Definitions: How Behat knows what to do

The execution of our test is possible because Mink comes packaged with a long list of definitions for every common browser operation. To see all of the available definitions, run behat --definitions from the command line. Out of the box, you'll see a long long list of functionality:

"Behat Mink Definitions"

Of course, eventually, you'll need to do something that's not prepackaged. For example, imagine that you need to authenticate before reaching a page. Your scenario might start like this:

Scenario: Edit your profile
  Given I am authenticated as "user@foo.com"
  # ...

If you finish this scenario and then try to execute this feature, you'll get an error - Behat doesn't know what to do with this new line!

Step definition snippet

Fortunately, included in the error is the exact code that you'll need to create this new definition. All definitions are methods that live inside a FeatureContext class. It's pretty simple: the regular expressions are defined as annotations, and the code to execute is the method itself:

<?php

/**
 * @Given /^I am authenticated as "([^"]*)"$/
 */
public function iAmAuthenticatedAs($email)
{
    // whatever code you need to authenticated as this email address
}

Now, when you re-run your test, the line Given I am authenticated as "user@foo.com" will match the regular expression above this method, and the method will be executed. By including quotes around user@foo.com, Behat guessed that you'd want this as a variable and makes it available in the method.

That's pretty much all there is to it! Inside your method definition, you can do anything. To mark a test as "failed", simply throw any type of exception. If no exception is thrown, the test "passes".

Install

It's never been easier to install Behat!

You can either install it as a PEAR package:

$ pear install behat/behat

Or download it as PHAR executable:

$ wget https://github.com/downloads/Behat/Behat/behat-2.0.1.phar

More more more!!!

Using Behat to test your web applications is a no-brainer. It allows you to focus on the features you need to deliver, while giving you the flexibility (via Mink) to execute your tests in a headless browser or a real browser.

Behat has a lot of other cool features, including multilingual support so that you can write your features in your native language. There's also hooks, configuration, and a lot more to learn about the language of the feature files, called ruby.

But for now, just dive in and start playing. Start with the quick intro and then graduate to working with Behat and Mink together.

Happy testing!

Written by

KNP Labs
KNP Labs

Comments