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: 153

Dependents: 4

Suggesters: 0

v1.0.3 2026-10-09 12:33 UTC

This package is auto-updated.

Last update: 2026-10-26 21:17:26 UTC


README

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: you supply the domain logic by implementing a few interfaces.

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.

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.

Used in Barn

This package is used in Barn. Learn about Barn. There, Scenario Bridge runs the scenarios captured in Barnspec through it, Port Generator writes the Port stubs, and Scenario Runner CLI scaffolds unit tests.

More docs

Internals ยท History

License

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