Skip to content

Scenario Provisioning: Thoughts on new feature? #183

Open
@ghost

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions