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
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
Thanks for this links!
But it seems its pretty hard to compete with phpspec and phpunit nowdays 😦
cool! Thanks. I will study them
Reblogged this on Sutoprise Avenue, A SutoCom Source.
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 🙂 )
Thank you for the article!
Also have a look at Codeception http://codeception.com/ – really outstanding tool
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.
One more tool https://github.com/danielstjules/pho