
Description
So I've been out of the PHP game for a few months and as a 'back-on-the-horse' exercise, I wanted to play around with Peridot as I really like the syntax (coming from a PHPUnit guy). While I was tinkering, I thought it'd be nice to have a feature wherein specific 'scenarios' are bound to a test, allowing the same test definition to run with different values (similar to data providers in PHPUnit). I wanted to take a stab at implementing this, so I forked the repo and implemented scenarios as a kind of proof of concept and was wondering what the Peridot powers that be think of the feature in general? Consider a FizzBuzz example:
function convertValueToFizzBuzz($value)
{
$response = '';
if ($value % 3 === 0) {
$response .= 'Fizz';
}
if ($value % 5 === 0) {
$response .= 'Buzz';
}
return ($response ?: $value);
}
A simple test for 'Fizz' conversion could be described as:
describe('convertValueToFizzBuzz($value)', function() {
context('when $value divisible by 3', function() {
it('should return "Fizz"', function() {
assert(convertValueToFizzBuzz(9) === 'Fizz');
});
});
});
However, it would be nice to test other values as well. This could be accomplished by looping over a value array within the test, but this just adds noise to the test itself. What I had in mind was adding a function to the base DSL that would attach a scenario to the last-added test (the test would run once for each scenario):
describe('convertValueToFizzBuzz($value)', function() {
context('when $value divisible by 3', function() {
it('should return "Fizz"', function() {
assert(convertValueToFizzBuzz($this->scenario['expected_fizz_value']) === 'Fizz');
});
inScenario(['expected_fizz_value' => -3]);
inScenario(['expected_fizz_value' => 3]);
inScenario(['expected_fizz_value' => 6]);
});
});
The idea is that a scenario is an object which is basically a glorified array. Each scenario in turn is injected into the scope right after a given test's setup functions as <test scope>->scenario
. The scenario is removed from the test scope immediately before the test teardown functions are invoked.
Because each test would be run multiple times, multiple events would be emitted per-test. This leads to some duplicate reporting, but the duplication makes it very easy to see which scenario is causing the test to fail:
$ bin/peridot fixtures/sample-scenario-spec.php
convertValueToFizzBuzz($value)
when $value divisible by 3
✓ should return "Fizz"
✓ should return "Fizz"
✓ should return "Fizz"
3 passing (0 ms)
<...changes made causing a scenario to fail...>
$ bin/peridot fixtures/sample-scenario-spec.php
convertValueToFizzBuzz($value)
when $value divisible by 3
✓ should return "Fizz"
1) should return "Fizz"
✓ should return "Fizz"
2 passing (0 ms)
1 failing
I know that this is a trivial example but hopefully it serves to illustrate the idea. Any thoughts?
Josh
Activity