Building a BDD framework with PHP


Do you know Jasmine, the BDD framework for JavaScript? This holidays I was looking for something like that in PHP and I didn’t found anything similar (please let me know if I’m wrong) (now I know a few of them thanks to Dave’s comment) . Because of that, and as an exercise, I hack a little bit building something similar for PHP.

I want to write as less code as I can (it’s only a proof of concept), so I will reuse the assertion framework or PHPUnit. As I’ve seen when studying Behat, we can use the assertion part as standalone functions. We only need to include 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 also can use something similar than 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 an 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 because this library is a proof of concept. There’re a lot of remaining things. What do you think?

Source code at github

About these ads

About Gonzalo Ayuso

Web Architect specialized in Open Source technologies. PHP, Python, JQuery, Dojo, PostgreSQL, CouchDB and node.js but always learning.

Posted on August 19, 2013, in php, PHPUnit, Symfony, Technology and tagged , , , , , . Bookmark the permalink. 11 Comments.

  1. There are quite a few out there, here’s the ones I can remember:

    github.com/davedevelopment/dspec (my own)
    github.com/noonat/pecs
    github.com/glenjamin/phptea

  2. cool! Thanks. I will study them

  3. i am surprised you don’t know about phpspec/phpspec
    it is the defacto, that is it ;)

    • phpspec wasn’t the thing that I had in mind. I was thinking about something like describe(‘name of the test with spaces’, function())
      (the idea behind Jasmine) phpspec is something different (is a bdd toolkit, but different) such as behat.

      (I also must admit that I wanted to play with closures :) )

  4. Thank you for the article!
    Also have a look at Codeception http://codeception.com/ – really outstanding tool

  5. Hi, I started my own implementation too :) To not do all the stuff ( and probably you don’t want to implement JUnit reporting, HTML reporting, events, filters, groups, etc) I made this as very tiny addon on top of PHPUnit. I was inspired by minitest, in which you can use both syntax modes: BDD and classical TDD.

    https://github.com/Codeception/Specify

    also assertions

    https://github.com/Codeception/Verify

    I think the only way to get it done with all features, is using PHPUnit on top.

  1. Pingback: Дайджест интересных новостей и материалов из мира PHP за последние две недели №24 (11.08.2013 — 25.08.2013) | Juds

  2. Pingback: PHP Digest №1 ( 11.08.2013 — 25.08.2013 ) | FASIGN Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 998 other followers

%d bloggers like this: