PHPackages                             ohffs/scenarios - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. ohffs/scenarios

ActiveLibrary[Testing &amp; Quality](/categories/testing)

ohffs/scenarios
===============

Easily create database helpers for given test scenarios

05PHP

Since Jun 8Pushed 9y ago1 watchersCompare

[ Source](https://github.com/ohnotnow/scenarios)[ Packagist](https://packagist.org/packages/ohffs/scenarios)[ RSS](/packages/ohffs-scenarios/feed)WikiDiscussions master Synced 2w ago

READMEChangelogDependenciesVersions (1)Used By (0)

Simple PHP Scenarios
====================

[](#simple-php-scenarios)

This is a *very* basic PHP class and trait to make using 'scenarios' easier. Initially it was written with Laravel phpunit tests in mind, but in theory it could be used for other things.

What are... 'Scenarios'?
------------------------

[](#what-are-scenarios)

When writing tests I often find myself having to do repetative things like this a lot in each test :

```
$admin = factory(User::class)->states('admin')->create();
$user = factory(User::class)->states('regular')->create();
$post = factory(Post::class, 3)->states('unpublished')->create(['user_id' => $user->id]);
...
```

That code gets repeated in maybe a dozen tests. So sometimes I write a helper function - sometimes not as it's quicker to just copy'n'paste the code from the previous test. So I decided to write a very simple helper which is pretty much a key/value store so that I could do something a little more expressive in the test like the following :

```
$this->scenarios()->playout('there is an admin and a user with three posts');
```

Usage
-----

[](#usage)

Assuming you want to use the trait :

```
class SomeTest {

    use \Ohffs\Scenarios\HasScenarios;

    public function setUp()
    {
        parent::setUp();
        $this->scenarios()->write('there is an unpublished post and an admin', function ($params) {
            $admin = factory(User::class)->states('admin')->create();
            $post = factory(Post::class)->states('unpublished')->create($params);
            return [$admin, $post];
        });
        $this->scenarios()->write('we have a published post', function () {
            return factory(Post::class)->states('published')->create();
        });
        $this->scenarios()->write('we have an admin', function () {
            return factory(User::class)->states('admin')->create();
        });
        $this->scenarios()->write('we have a regular user', function () {
            return factory(User::class)->states('regular')->create();
        });
    }

    public function test_an_admin_can_mark_a_post_as_published()
    {
        [$admin, $post] = $this->scenarios()
                            ->playout('there is an unpublished post and an admin', ['title' => 'A Post Title'])
                            ->andReturnResults();

        $response = $this->actingAs($admin)->post('/posts/' . $post->id, ['status' => 'published']);

        $this->assertEquals(1, Post::published()->count());
    }

    public function test_an_admin_can_delete_a_post()
    {
        [$admin, $post] = $this->scenarios()->playout('there is an unpublished post and an admin')->andReturnResults();

        $response = $this->actingAs($admin)->delete('/posts/' . $post->id);

        $this->assertEquals(0, Post::count());
    }

    public function test_a_user_cant_delete_posts_that_are_not_theirs()
    {
        [$post, $badUser] = $this->scenarios()
                                ->playout('we have a published post')
                                ->andAlso('we have a regular user')
                                ->andReturnResults();

        $response = $this->actingAs($badUser)->delete('/posts/' . $post->id);

        $response->assertStatus(302);
        $this->assertEquals(1, Post::count());
    }
}
```

Notes
-----

[](#notes)

If you try and 'playout' a scenario which doesn't exist, the code will throw an \\InvalidArgumentException.

If your scenario list only calls one 'thing' then it will be returned 'as is', otherwise it'll return an array of the things. Eg.

```
$this->scenarios()->write('we have a regular user', function () {
    return ['username' => 'jenny', 'status' => 'normal'];
});
$this->scenarios()->write('we have a super user', function () {
    return ['username' => 'marlene', 'status' => 'admin'];
});

$admin = $this->scenarios()->playout('we have a super user')->andReturnResults();
$user = $this->scenarios()->playout('we have a regular user')->andReturnResults();
[$user, $admin] = $this->scenarios()->playout('we have a regular user')->andAlso('we have a super user')->andReturnResults();
```

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity4

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/5472be37b2cbedfa6c905bb674cb5780378cf2adcfc47befe01ad7bb4d14f734?d=identicon)[ohnotnow](/maintainers/ohnotnow)

---

Top Contributors

[![ohnotnow](https://avatars.githubusercontent.com/u/6471843?v=4)](https://github.com/ohnotnow "ohnotnow (6 commits)")

---

Tags

phptesting

### Embed Badge

![Health badge](/badges/ohffs-scenarios/health.svg)

```
[![Health](https://phpackages.com/badges/ohffs-scenarios/health.svg)](https://phpackages.com/packages/ohffs-scenarios)
```

###  Alternatives

[dms/phpunit-arraysubset-asserts

This package provides ArraySubset and related asserts once deprecated in PHPUnit 8

14228.7M341](/packages/dms-phpunit-arraysubset-asserts)[phpbenchmark/phpbenchmark

Easy to use benchmark toolkit for your PHP-application. This library contains classes for comparing algorithms as well as benchmarking application responses

8011.5k2](/packages/phpbenchmark-phpbenchmark)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
