fbarrento / data-factory
Test data factory for PHP
Fund package maintenance!
fbarrento
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/fbarrento/data-factory
Requires
- php: ^8.2.0
Requires (Dev)
- fakerphp/faker: ^1.24
- laravel/pint: ^1.24.0
- peckphp/peck: ^0.1.3
- pestphp/pest: ^3.8|^4.1.0
- pestphp/pest-plugin-type-coverage: ^v3.6|^4.0.2
- phpstan/phpstan: ^2.1.26
- rector/rector: ^2.1.7
- symfony/var-dumper: ^7.3.3
README
The modern test data factory for PEST. Write cleaner, more maintainable PHP tests with expressive factories.
Inspired by Laravel's Eloquent factories, Data Factory brings the same elegant API to any PHP project—no framework required.
Requires PHP 8.2+ | Fully tested on PHP 8.2, 8.3, 8.4 across Windows, Linux, and macOS
Features
- ✅ Write DRY test code - Define test data once, reuse everywhere
- ✅ Readable test assertions - Clear intent with named states like
->succeeded() - ✅ Easy complex objects - Create nested graphs without boilerplate
- ✅ Built with PEST in mind - Works with any PHP testing framework, optimized for PEST
- ✅ Framework-agnostic - Works with any PHP class, not tied to Eloquent
- ✅ Type-safe factories - Modern type hints with 100% type coverage
- ✅ Faker integration - Realistic test data out of the box
Installation
Install via Composer:
composer require fbarrento/data-factory --dev
Why Use Data Factories for Testing?
The Problem: Test setup code is repetitive, hard to maintain, and clutters your test files.
// ❌ Without factories - repetitive and brittle it('processes deployment', function () { $deployment = [ 'id' => '123e4567-e89b-12d3-a456-426614174000', 'status' => 'deployment.succeeded', 'branch_name' => 'main', 'commit_hash' => 'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0', 'commit_message' => 'Deploy feature X to production', 'failure_reason' => null, 'php_major_version' => '8.4', 'uses_octane' => true, 'started_at' => '2024-01-15 10:00:00', 'finished_at' => '2024-01-15 10:05:00', ]; // Your actual test logic here... });
// ✅ With factories - clean and focused it('processes deployment', function () { $deployment = Deployment::factory()->succeeded()->make(); // Your actual test logic here - clear and focused! });
The Benefits:
- DRY (Don't Repeat Yourself) - Define test data once, reuse across all tests
- Maintainability - Change data structure in one place, not hundreds of tests
- Readability -
->succeeded()is clearer than 10 lines of setup - Flexibility - Easy to test edge cases with different states
- Focus - Spend time testing behavior, not setting up data
Quick Start
// tests/Factories/DeploymentFactory.php use FBarrento\DataFactory\Factory; class DeploymentFactory extends Factory { protected function definition(): array { return [ 'id' => $this->fake->uuid(), 'status' => 'pending', 'branch_name' => 'main', 'commit_hash' => $this->fake->sha1(), ]; } public function succeeded(): static { return $this->state(['status' => 'deployment.succeeded']); } } // tests/Feature/DeploymentTest.php it('handles successful deployments', function () { $deployment = Deployment::factory()->succeeded()->make(); expect($deployment->status)->toBe('deployment.succeeded'); }); it('creates multiple test deployments', function () { $deployments = Deployment::factory()->count(5)->make(); expect($deployments)->toHaveCount(5); });
Documentation
- Getting Started - Overview and feature list
- Installation - Install and setup
- Basic Usage - Create your first factory
- Faker Integration - Generate realistic fake data
- States - Define reusable variations
- Sequences - Cycle through values
- Nested Factories - Build complex object graphs
- Array Factories - Generate arrays for JSON/API responses
- Class Integration - Integrate factories with your classes using HasDataFactory trait
- Advanced Examples - Real-world Laravel Cloud API examples
- Testing - Use factories in PEST tests
Roadmap
Features under consideration for future releases:
- 🎯
raw()method - Return attribute arrays without instantiating objects, useful for testing raw data or API payloads$attributes = Vehicle::factory()->raw(); // Returns ['make' => '...', 'model' => '...']
- 🪝
afterMaking()callbacks - Post-processing hooks for generated data, enabling validation or side effectsVehicle::factory() ->afterMaking(fn($vehicle) => logger()->info('Made vehicle', ['id' => $vehicle->id])) ->make();
- 🗂️ Export to JSON - Save datasets as JSON fixtures for testing or seeding
Vehicle::factory()->count(1000)->toJson('fixtures/vehicles.json');
- 📦 Export to Arrays - Transform objects to nested array structures
$array = Customer::factory()->count(100)->toArray();
- ⚡ Streaming/Chunking - Process large datasets (100k+ records) without memory issues
Vehicle::factory()->count(200000)->chunk(1000)->toJson('fixtures/vehicles.json');
- 🚨 Exception Handling - Custom exceptions with helpful error messages for configuration and validation errors
Have ideas for other features? Open an issue or submit a PR!
Contributing
We welcome contributions! Data Factory is built with high quality standards:
- ✅ 100% test coverage
- ✅ 100% type coverage
- ✅ PHPStan level 9
- ✅ Modern PHP 8.2+ patterns
Quick Start for Contributors:
# Run all quality checks composer test # Format code composer lint # Run tests with coverage composer test:unit
For detailed contributing guidelines, development setup, and code standards, see CONTRIBUTING.md.
References
- Stop Writing Arrays in Your Tests: Laravel Factories for Data Objects - The article that inspired this package
License
Data Factory is open-sourced software licensed under the MIT license.