Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Building a BDD Framework with PHP

DZone's Guide to

Building a BDD Framework with PHP

· DevOps Zone
Free Resource

Download the blueprint that can take a company of any maturity level all the way up to enterprise-scale continuous delivery using a combination of Automic Release Automation, Automic’s 20+ years of business automation experience, and the proven tools and practices the company is already leveraging.

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

Download the ‘Practical Blueprint to Continuous Delivery’ to learn how Automic Release Automation can help you begin or continue your company’s digital transformation.

Topics:

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

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

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

X

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

{{ parent.tldr }}

{{ parent.urlSource.name }}