Setup
Non-CakePHP apps
For non-CakePHP applications, use whatever method your framework provides for managing the test database, or opt for the universal test-database-cleaner.
Define your DB connections in your test bootstrap.php as described in the CakePHP cookbook.
CakePHP apps
To be able to bake your factories, load the CakephpFixtureFactories plugin in your plugins.php file or your src/Application.php file:
protected function bootstrapCli(): void
{
// Load more plugins here
if (Configure::read('debug')) {
$this->addPlugin('CakephpFixtureFactories');
}
}We recommend using migrations for managing the schema of your test DB with the CakePHP Migrations plugin.
Table Truncation
Test data must be cleaned between tests to avoid entity collisions and unexpected results. There are several strategies for this when working with fixtures and fixture factories.
CakePHP ships with Fixture State Managers and provides the TruncateStrategy (truncate all tables after each test run) as well as the TransactionStrategy (create a transaction and roll it back after each test run).
The CakePHP test suite light plugin provides the TriggerStrategy which will set up a trigger in your database to clean up the tables after each test run. This might require admin/root permission access, so this is not necessarily possible on all setups.
// In config/app.php
'TestSuite' => [
'fixtureStrategy' => \CakephpFixtureFactories\TestSuite\TriggerStrategy::class,
],Factory Transaction Strategy (Recommended)
This plugin provides the FactoryTransactionStrategy which automatically:
- Wraps all database operations in transactions
- Rolls back after each test (both factory and application data)
- Resets unique generator state (fixes OverflowException issues)
- Tracks which tables are written to by fixture factories
Unlike the standard TransactionStrategy, this doesn't require manually listing fixtures — in fact, the strategy works best if you don't use classic $fixtures arrays at all.
CakePHP 5.2+ (global configuration)
In CakePHP 5.2+, configure the fixture strategy globally in config/app.php:
'TestSuite' => [
'fixtureStrategy' => \CakephpFixtureFactories\TestSuite\FactoryTransactionStrategy::class,
],This applies the strategy to all test cases automatically. No traits needed.
Tip: See
config/app.example.phpin this plugin for a full list of available configuration options, including generator type, seed, and instance-level generator management.
CakePHP 5.0–5.1 (trait-based)
For older CakePHP versions, use FactoryTransactionTrait. Two patterns:
namespace App\Test;
use Cake\TestSuite\TestCase;
use CakephpFixtureFactories\TestSuite\FactoryTransactionTrait;
abstract class AppTestCase extends TestCase
{
use FactoryTransactionTrait;
}
// Then extend AppTestCase in every test:
class MyTest extends AppTestCase
{
// Strategy is automatically applied.
}use CakephpFixtureFactories\TestSuite\FactoryTransactionTrait;
class MyTest extends TestCase
{
use FactoryTransactionTrait;
public function testSomething(): void
{
$article = ArticleFactory::make()->persistEntity();
$this->Articles->save($article);
// All data rolled back; generator state reset.
}
}Prefer the shared AppTestCase route — the per-test trait pattern works too but means repeating yourself.
Benefits
- No need to manually list
$fixtures - All data is rolled back - factory data AND application code modifications
- Faster than truncation strategies
- Solves unique generator state accumulation - the strategy resets generator state after each test, preventing
OverflowExceptionwhen usingunique()modifiers - Works seamlessly with nested associations
Note: Table tracking only captures tables written via
factory->persist(). The transaction rollback still handles all data modifications regardless of source (factories, controllers, models, etc.).