Over a million developers have joined DZone.

Building a BDD Framework with PHP

· DevOps Zone

The DevOps zone is brought to you in partnership with Sonatype Nexus. The Nexus suite helps scale your DevOps delivery with continuous component intelligence integrated into development tools, including Eclipse, IntelliJ, Jenkins, Bamboo, SonarQube and more. Schedule a demo today

Have you heard of Jasmine, the BDD framework for JavaScript? Over the holidays I was looking for something like that for PHP but I couldn’t find anything similar (please let me know if I’m wrong). (Now I know of a few of them thanks to Dave’s comment.) Because of that, and as an exercise, I hacked together something similar in PHP.

I wanted to write as little code as I could (since it’s only a proof of concept), so I reused the assertion framework or PHPUnit. As I’ve seen when studying Behat, we can use the assertion part for standalone functions. We only need to include the vendor/phpunit/phpunit/PHPUnit/Framework/Assert/Functions.php file.

Here you can see one example:

class StringCalculator
    public function add($string)
        return (int)array_sum(explode(",", $string));

$stringCalculator = new StringCalculator;

describe("add mull returns zero", function () use ($stringCalculator) {
        assertEquals(null, $stringCalculator->add(""));

describe("1,1 should return 2", function () use ($stringCalculator) {
        assertEquals(2, $stringCalculator->add("1,1"));

We can also use something similar to DataProvider in PHPUnit:

describe("add number returns number", function ($expected, $actual, $message) use ($stringCalculator) {
        assertEquals($expected, $stringCalculator->add($actual), $message);
    }, [
        ['expected' => 1, 'actual' => "1", 'message' => 'add 1'],
        ['expected' => 2, 'actual' => "2", 'message' => 'add 1'],
        ['expected' => 10, 'actual' => "10", 'message' => 'add 10'],

And if we need mocks we can use Mockery, for example:

class Temperature

    public function __construct($service)
        $this->_service = $service;

    public function average()
        $total = 0;
        for ($i=0;$i<3;$i++) {
            $total += $this->_service->readTemp();
        return $total/3;

$service = m::mock('service');

describe("testing mocks with mockery", function() use ($service) {
        $service->shouldReceive('readTemp')->andReturn(11, 12, 13);
        $temperature = new Temperature($service);
        assertEquals(12, $temperature->average(), "dummy message");

I’ve created a small console application to run the test suites using Symfony console and Symfony finder components. We can run it with:

php ./bin/console.php texter:run ./tests

Beware that this library is a proof of concept. There’re a lot of things remaining. What do you think?

Source code at GitHub

The DevOps zone is brought to you in partnership with Sonatype Nexus. Use the Nexus Suite to automate your software supply chain and ensure you're using the highest quality open source components at every step of the development lifecycle. Get Nexus today


Published at DZone with permission of Gonzalo Ayuso, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}