PHPackages                             lapaz/quick-brown-fox - 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. [Database &amp; ORM](/categories/database)
4. /
5. lapaz/quick-brown-fox

ActiveLibrary[Database &amp; ORM](/categories/database)

lapaz/quick-brown-fox
=====================

ORM independent RDB fixture data generator

0.4.5(1y ago)95.3k↓44.2%11MITPHPPHP ^8.0

Since Dec 15Pushed 1y ago1 watchersCompare

[ Source](https://github.com/LapazPhp/QuickBrownFox)[ Packagist](https://packagist.org/packages/lapaz/quick-brown-fox)[ RSS](/packages/lapaz-quick-brown-fox/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (3)Versions (17)Used By (1)

QuickBrownFox
=============

[](#quickbrownfox)

[![PHP Composer](https://github.com/LapazPhp/QuickBrownFox/actions/workflows/php.yml/badge.svg?branch=master)](https://github.com/LapazPhp/QuickBrownFox/actions/workflows/php.yml)

ORM independent RDB fixture data generator.

Basic Usage
-----------

[](#basic-usage)

At first, define a session manager in your DI container or service locator:

```
use Lapaz\QuickBrownFox\SessionManagerInterface;
use Lapaz\QuickBrownFox\EasySessionManager;

// $container points some application scope service locator
$container->set(SessionManagerInterface::class, function() use ($container) {
    return new EasySessionManager($container->get('dbal.connection'));
    // or return new EasySessionManager([/*DBAL connection parameters*/]);
});
```

Prepare new test session in your test case:

```
use PHPUnit\Framework\TestCase;
use Lapaz\QuickBrownFox\SessionManagerInterface;

class BookRepositoryTest extends TestCase
{
    protected $session;

    protected function setUp()
    {
        /** @var ContainerInterface $container */
        $this->session = $container->get(SessionManagerInterface::class)->newSession();
    }
}
```

Session indicates single testing context. Database tables are automatically cleaned up in each sessions. `tearDown` method is not necessary. So, you can see the last state of database after test.

### generate

[](#generate)

Test your repository using randomly generated data by `generate` method:

```
    public function testFindBook()
    {
        $this->session->into('books')->generate(10);

        $books = (new BookRepository($this->connection))->findAll();
        $this->assertCount(10, $books);
        $this->assertNotNull($books[0]->getAuthor());
    }
```

In above example, `generate` method generates 10 random books. You don't need to care column definition. QuickBrownFox automatically fills non-null columns with random values.

Also you don't need to care relative tables because foreign key constraints are resolved automatically. If depending table is not filled yet, QuickBrownFox generates data for it.

### load

[](#load)

You can test with detailed data using `load` method:

```
    public function testGetBook()
    {
        $this->session->into('books')->load([
            ['id' => 1, 'title' => 'Design Pattern'],
            ['id' => 2, 'title' => 'Refactoring'],
        ]);

        $repository = new BookRepository($this->connection);

        $this->assertEquals('Design Pattern', $repository->get(1)->getTitle());
        $this->assertEquals('Refactoring', $repository->get(2)->getTitle());
        $this->assertNull($repository->get(3));
    }
```

In this case, `load` method loads specific data. If you don't specify some columns or relationships, QuickBrownFox fills them with random values.

### with

[](#with)

You can specify automatically filled value patterns using `with` method:

```
    public function testFindBook()
    {
        $this->session->into('books')->with(function($i) {
            return [
                'title' => 'Design Pattern ' . ($i + 1),
                'code' => sprintf('000-000-%03d', $i),
            ];
        })->generate(10);

        // test code here
    }

    public function testGetBook()
    {
        $this->session->into('books')->with([
            'preferred' => true,
            'rating' => function($i) { return 80 + $i * 5; },
        ])->load([
            ['id' => 1, 'title' => 'Design Pattern'],
            ['id' => 2, 'title' => 'Refactoring'],
        ]);

        // test code here
    }
```

`with` method sets common attributes for each data by callable which returns array. You can also use an array which has callable or constant values.

Advanced Usage
--------------

[](#advanced-usage)

### Predefined Fixtures and Generators

[](#predefined-fixtures-and-generators)

QuickBrownFox supports predefined fixtures and generators.

```
use Lapaz\QuickBrownFox\SessionManagerInterface;
use Lapaz\QuickBrownFox\FixtureManager;

// $container points some application scope service locator
$container->set(SessionManagerInterface::class, function() use ($container) {
    $fixtures = new FixtureManager();

    $fixtures->table('authors', function ($td) {
        $td->fixture('GoF')->define([
            ['id' => 1, 'name' => "Erich Gamma"],
            ['id' => 2, 'name' => "Richard Helm"],
            ['id' => 3, 'name' => "Ralph Johnson"],
            ['id' => 4, 'name' => "John Vlissides"],
        ]);
    });

    $fixtures->table('books', function ($td) {
        $td->generator('DesignPattern-N')->define(function($i) {
            return [
                'title' => 'Design Pattern ' . ($i + 1),
                'code' => sprintf('000-000-%03d', $i),
                'author_id' => 1,
            ];
        });
    });

    return $fixtures->createSessionManager($container->get('dbal.connection'));
    // or return $fixtures->createSessionManager([/*DBAL connection parameters*/]);
});
```

You can use named fixtures and generators in your test:

```
    public function testFindBook()
    {
        // Loads 4 gangs.
        $this->session->into('authors')->load('GoF');

        // Bind 8 books to 4 gangs as authors.
        $this->session->into('books')->with('DesignPattern-N')->with([
            'author_id' => function($i) { return $i % 4 + 1; },
        ])->generate(8);

        $books = (new BookRepository($this->connection))->findAll();
        $this->assertEquals("Design Pattern 1", $book[0]->getTitle());
        $this->assertEquals("Erich Gamma", $book[0]->getAuthor()->getName());

        $this->assertEquals("Design Pattern 8", $book[7]->getTitle());
        $this->assertEquals("John Vlissides", $book[7]->getAuthor()->getName());
    }
```

- `load` method can load predefined fixture by name.
- `with` method can set predefined generator by name.

It's useful when you have some common data structure in your application.

You can use `with` method multiple times. They are merged.

### Default Values

[](#default-values)

FixtureManager provides `defaults` method to customize random value generation. It's useful when table has some semantic constraints as its schema definition.

```
    $fixtures->table('books', function ($td) {
        $td->defaults([
            'type' => function() {
                return mt_rand(1, 3); // books.type must be 1, 2 or 3
            }
        ]);
    });
```

In above example, `type` column is filled with random value between 1 and 3 even if not specified by `with`.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance38

Infrequent updates — may be unmaintained

Popularity31

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity66

Established project with proven stability

 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.

###  Release Activity

Cadence

Every ~181 days

Recently: every ~11 days

Total

15

Last Release

537d ago

PHP version history (4 changes)0.1.0PHP ^5.6 || ^7.0

0.2.0PHP ^7.1 || ^8.0

0.3.0PHP ^7.4 || ^8.0

0.4.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/15b77626b4e66c3b9bff13810f781e379f2da5e9e6d7194956ae5a14a3f2eed5?d=identicon)[tanakahisateru](/maintainers/tanakahisateru)

---

Top Contributors

[![tanakahisateru](https://avatars.githubusercontent.com/u/403893?v=4)](https://github.com/tanakahisateru "tanakahisateru (63 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/lapaz-quick-brown-fox/health.svg)

```
[![Health](https://phpackages.com/badges/lapaz-quick-brown-fox/health.svg)](https://phpackages.com/packages/lapaz-quick-brown-fox)
```

###  Alternatives

[martin-georgiev/postgresql-for-doctrine

Extends Doctrine with native PostgreSQL support for arrays, JSONB, ranges, PostGIS geometries, text search, ltree, uuid, and 100+ PostgreSQL-specific functions.

4485.3M4](/packages/martin-georgiev-postgresql-for-doctrine)[damienharper/auditor-bundle

Integrate auditor library in your Symfony projects.

4542.8M](/packages/damienharper-auditor-bundle)[sonata-project/entity-audit-bundle

Audit for Doctrine Entities

644989.8k1](/packages/sonata-project-entity-audit-bundle)[webfactory/slimdump

slimdump is a little tool to help you creating dumps of large MySQL-databases.

188124.8k1](/packages/webfactory-slimdump)[overtrue/laravel-versionable

Make Laravel model versionable.

585308.0k5](/packages/overtrue-laravel-versionable)[bolt/core

🧿 Bolt Core

585142.5k54](/packages/bolt-core)

PHPackages © 2026

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