Search by

rmb32 / scenario-runner

rogerbarnfather

A small, generic Given/When/Then scenario execution engine โ€” Act/Arrange/Assert/Authenticate ports, no framework or transport opinions

Package info

bitbucket.org/rmb32/scenario-runner/

Homepage

pkg:composer/rmb32/scenario-runner

Statistics

Installs: 7

Dependents: 1

Suggesters: 0

v1.0.0 2026-10-07 12:20 UTC

This package is auto-updated.

Last update: 2026-10-07 18:34:49 UTC


README

Part of BarnSuite.

A small, generic Given/When/Then execution engine. Describe your acceptance scenarios as plain data โ€” areas of business, roles, stories, scenarios that arrange some facts, perform one action and assert some facts โ€” and Scenario Runner runs them and reports exactly what passed and failed. It has no framework, storage or transport opinions and knows nothing about Barnspec: you supply the domain logic by implementing a few interfaces.

To run scenarios you captured in Barnspec, use Scenario Bridge.

Requirements

  • PHP 8.5+, ext-dom

Installation

composer require rmb32/scenario-runner

The ports you implement

PortDoes
Arrangesets up one given fact's state
Assertanswers whether one then fact now holds
Actperforms the action, returns the actual outcome (Accepted / Rejected)
Authenticateestablishes a role as the one performing a story
ReadStorage / WriteStoragethe one piece of state Scenario Runner itself touches

Each fact, action and role in your data names its own handler class. By default it is built with new $className(). Give the builder a PortFactory to build them any other way, such as from your application's container:

$tester = new AreaOfBusinessTesterBuilder(
    ports: new ContainerPorts(),          // implements PortFactory
    storages: new MyStorageFactory(),     // implements StorageFactory
)->build();
  • With a StorageFactory, every Scenario runs in a storage of its own, so the order Scenarios run in never matters.
  • A role is authenticated at the start of every Scenario it performs.
  • A PortFactory that also implements BeforeEachScenario is told before each Scenario begins: the place to empty a test database.
  • A Port that throws fails only its own Scenario. It is reported as crashed, with where and why (๐Ÿ’ฅ โ€ฆ the Scenario crashed in Given: RuntimeException: โ€ฆ), and every other Scenario still runs.
  • A Given or Then may use the same fact more than once, with different arguments; each use runs, in order.

Port Generator writes stubs for all of these from your captured Barnspec vocabulary.

Running scenarios

use Rmb32\ScenarioRunner\Api\Factory\AreaOfBusinessTesterBuilder;
use Rmb32\ScenarioRunner\Api\ValueObject\CliTestMessageFormatter;

$tester = new AreaOfBusinessTesterBuilder()->build();

$result = $tester->test($areaOfBusinessData, $storage, $storage);

$result->passed();   // bool
$formatter = new CliTestMessageFormatter();
echo $result->message($formatter); // coloured pass/fail report

$areaOfBusinessData is built from the AreaOfBusinessData / RoleData / StoryData / ScenarioData value objects; $storage implements both ReadStorage and WriteStorage.

Reporting

  • CliTestMessageFormatter โ€” ANSI-coloured terminal output.
  • XmlTestReport โ€” a JUnit-style XML report most CI systems display natively.
  • Observer targets (CliPrintTarget, SummaryTarget, XmlExportTarget, NdjsonExportTarget, CsvExportTarget) with filters (FailuresOnlyFilter, PassesOnlyFilter, RoleFilter, StoryFilter, ScenarioFilter) let you send the same result to several places, each with its own view. Implement OutputSink to send output somewhere new.

Scaffolding unit tests

The optional scenario-runner command creates an empty PHPUnit test for a Work ticket. It lives in scenario-runner-cli.

Related packages

More docs

Internals ยท History

License

Proprietary. See LICENSE. Copyright (c) Roger Barnfather.