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

Easily enforce open source policies in real time and reduce MTTRs from six weeks to six seconds with the Sonatype Nexus Platform. See for yourself - Free Vulnerability Scanner. 

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

Automate open source governance at scale across the entire software supply chain with the Nexus Platform. Learn more.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}