Video icon 64
Learning to code? Skill up faster with our practical video courses. Start your free trial today.
Advertisement

BDD With Behat

by

The BDD PHP framework Behat, allows you to test your PHP applications using human-readable sentences to write features and scenarios about how your applications should behave in order to test out its functionality. We can then run these tests to see if our application is behaving as expected. Let's spend about 15 minutes quickly going over Behat's installation process and learn how we can test our PHP applications behavior using the basics.


Installation

To begin testing with Behat, we just need to install it on our local development machine. I'll be using Composer, but you can take a look at a the documentation for additional installation methods.

Within your PHP application (I have a blank PHP app named phpbehat created in advance) create a composer.json file with the following code to load in Behat:

{
	"require": {
		"behat/behat": "2.4.*@stable"
	},
	"minimum-stability": "dev",
	"config": {
		"bin-dir": "bin/"
	}
}

In your terminal we can install it using the following command:

composer update

We should now be able to run the bin/behat command to work with Behat.


Creating Features

We always begin by creating a new feature. A feature is something that we can use to describe a feature of our application and then implement it to get the test to pass.

A feature, at its simplest, consists of:

  • Human-readable, plain text.
  • Uses a .feature extension.
  • Contains the feature's benefit, role, and the feature itself.
  • May hold a list of scenarios.

Now I can't show you how to test all possible features for an application, as that would take far too long. But what I can do is show you how to go about writing a basic feature and you can adapt this code to make it work for your specific application.

Testing the Phpadder Class

To avoid complicating the learning process, let's create a very simple Phpadder.php file which contains a couple methods that we can use to add two numbers together and display their sum.

class Phpadder {

	private $a;
	private $b;
	public $sum;

	public function __construct($a, $b) {
		$this->a = $a;
		$this->b = $b;
	}

	public function add() {
		$this->sum = $this->a + $this->b;
	}

	public function display() {
		return $this->sum;
	}
}

This creates a new class named Phpadder. We have a few properties to hold the first ($a) and second ($b) numbers to be added, as well as a $sum property to hold the values's sum.

Next, we have our constructor which initializes our properties. Then we have an add method to add the two numbers together and finally a display method to display the sum of the two numbers.

Adder Feature

Let's now test this Phpadder class. Create a new .feature file along with the following code:

# features/phpadder.feature
Feature: adder
	In order to display the sum of two numbers
	As anybody
	I need to provide two numbers

We start out by giving our feature a name of adder. Then we specify, on three lines, the feature's benefit, role, and finally the feature itself. It should be fairly self explanatory.

Now that we have our feature, let's start writing our scenarios.


Creating Scenarios

Anytime we create a feature we can define scenarios that describe how that feature behaves given certain conditions. Scenario's follow the same basic layout consisting of the scenario's description, a context, an event, and an outcome.

Let's create a scenario to test out our Phpadder application:

Scenario: Display the sum of two provided numbers
	Given I have the number 50 and the number 25
	When I add them together
	Then I should get 75

We begin with our scenario description, we then list out that we start with the two numbers of 50 and 25 and when they are added together it should display the sum of 75.

You can also have multiple contexts, events, and outcomes as well using the following keywords: And and But. Here's a modified example of the previous scenario where we'll use And:

Scenario: Display the sum of two provided numbers
	Given I have the number 50 and the number 25
	And I have a third number of 25
	When I add them together
	Then I should get 100

Creating Step Definitions

A step is nothing more than a PHP function which is made up of a keyword, a regular expression, and a callback function. Each statement within your scenario will be matched to a step. These steps define what should happen given one of your statements are called within a scenario. You store all of your steps within the features/bootstrap/FeatureContext.php file.

The "Given" Step

In our FeatureContext.php file (you may need to create this), we need to write a step for each of our statements, using its name as the function name. We'll start with the "Given I have the number" statement:

# features/bootstrap/FeaturesContext.php

require("Phpadder.php");

use Behat\Behat\Context\BehatContext, 
	Behat\Behat\Exception\PendingException;

use Behat\Gherkin\Node\PyStringNode,
	Behat\Gherkin\Node\TableNode;
	
class FeatureContext extends BehatContext {

	private $Adder;
	
	/**
	 * @Given /^I have the number (\d+) and the number (\d+)$/
	 */
	public function iHaveTheNumberAndTheNumber($a, $b) {
		$this->Adder = new Phpadder($a, $b);
	}

First, we create a new PHP file, require in our Phpadder.php file (the file that we're testing), and then we use a few Behat classes with use statements, right after.

Next, we create our FeatureContext class and have it extend the BehatContext class.

Our class has only one property, $Adder, which will hold a Phpadder object.

Finally, we create a method for our first step using the same name as the statement. Our step has a regular expression, found within the method's comment. This regular expression is used to match the step to a scenario statement. Within this method we simply assign a new Phpadder object to our $this->Adder property so that the rest of our methods have access to the same Phpadder object.

Now, you've probably noticed the @Given keyword within your function's comment, this is actually an annotation so that the different types of steps can be identified. You can use @Given, @When, and @Then.

Now we just need to write the last two steps.

The "When" Step

/**
 * @When /^I add them together$/
 */
public function iAddThemTogether() {
	$this->Adder->add();
}

This step simply uses our $this->Adder object's add method to add the two numbers together.

The "Then" Step

/** 
 * @Then /^I should get (\d+)$/ 
 */
public function iShouldGet($sum) {
	if ($this->Adder->sum != $sum) {
		throw new Exception("Actual sum: ".$this->Adder->sum);
	}
	$this->Adder->display();
}

This step starts off by checking if the actual sum (retrieved using our $this->Adder object and its sum property) is not equal to the expected sum. If this evaluates to true that means we need to have Behat show a failure. To do so, we'll just throw a new exception displaying the actual sum so we can compare. Otherwise, we call our display method.

Time to run the tests.


Running the Tests

Now that we have our features, scenarios, and steps laid out, let's run our tests using the following command:

bin/behat

You should see the following success messages inside of your terminal:

testing-success

You can ensure that your tests are running correctly, by simply breaking something in your Phpadder.php file so that it doesn't run quite the same way your test expects it to. For example, if we change the add method to instead use subtraction, like so:

public function add() {
	$this->sum = $this->a - $this->b;
}

And then we rerun our tests: bin/behat. You can see in our terminal, we now have a failing test, because it's no longer adding our numbers but subtracting them:

testing-fail

Conclusion

In conclusion, you can follow a small four step process for testing your PHP apps using Behat:

  1. Define a Feature
  2. Define a Scenario
  3. Define Step Definitions
  4. Run the tests using bin/behat

So, with just that small amount of code, we should now have a basic understanding of how to work with Behat to test our PHP applications. For more information about working with Behat please checkout their documentation.

Advertisement