VOOZH about

URL: https://deepwiki.com/hypervel/testbench/7.3-testing-with-database-traits

⇱ Testing with Database Traits | hypervel/testbench | DeepWiki


Loading...
Last indexed: 7 February 2026 (93289f)
Menu

Testing with Database Traits

Purpose and Scope

This document covers practical patterns for database testing using the HandlesDatabases trait. It explains the database lifecycle hooks provided by the trait, how to define migrations and seeders in tests, and strategies for maintaining database isolation between tests.

For information about the specific migrations and migration lifecycle, see Database Migrations in Tests. For details on creating test data with factories, see Model Factories. For the core TestCase lifecycle that orchestrates these database operations, see Test Lifecycle and Hooks.

Sources: src/Concerns/HandlesDatabases.php1-56

HandlesDatabases Trait Overview

The HandlesDatabases trait provides database lifecycle hooks that integrate with the TestCase setup and teardown process. The trait is included in TestCase and offers five protected methods for managing database state during testing.

Available Methods

MethodPurposeWhen Called
defineDatabaseMigrations()Define database migrations to run before testsDuring test setup
destroyDatabaseMigrations()Clean up migrations after testsDuring test teardown
defineDatabaseSeeders()Define seeders to populate test dataAfter migrations are defined
defineDatabaseMigrationsAfterDatabaseRefreshed()Define migrations to run after database refreshAfter a database refresh operation
setUpDatabaseRequirements(callable $callback)Orchestrate the complete database setup lifecycleCalled by tests to manage full setup

Sources: src/Concerns/HandlesDatabases.php8-56

Database Lifecycle Integration

The HandlesDatabases trait integrates with the TestCase lifecycle to provide automatic database setup and teardown. The following diagram shows how the trait methods interact with the test execution flow.

Database Lifecycle Sequence Diagram


Sources: src/Concerns/HandlesDatabases.php15-26

Defining Database Migrations

The defineDatabaseMigrations() method is called during test setup to establish the database schema. Override this method to load migrations or manually create tables.

Method Signature


src/Concerns/HandlesDatabases.php15-18

Usage Pattern: Loading Migration Files


Usage Pattern: Manual Schema Definition

For simple tests, you can define the schema directly:


Sources: src/Concerns/HandlesDatabases.php15-18 workbench/config/database.php10-15

Destroying Database Migrations

The destroyDatabaseMigrations() method is called during test teardown to clean up the database schema. This ensures test isolation by removing any tables or data created during the test.

Method Signature


src/Concerns/HandlesDatabases.php23-26

Usage Pattern: Rolling Back Migrations


Usage Pattern: Manual Schema Destruction


Sources: src/Concerns/HandlesDatabases.php23-26

Defining Database Seeders

The defineDatabaseSeeders() method is called after migrations are defined to populate the database with test data. This is useful for tests that require specific initial state.

Method Signature


src/Concerns/HandlesDatabases.php31-34

Usage Pattern: Running Seeder Classes


Usage Pattern: Inline Data Creation


Sources: src/Concerns/HandlesDatabases.php31-34

Database Refresh Patterns

The defineDatabaseMigrationsAfterDatabaseRefreshed() method handles the case where the database is refreshed during the test. This is useful for tests that need to reset the database to a clean state mid-test.

Method Signature


src/Concerns/HandlesDatabases.php39-42

Refresh Lifecycle Diagram


Usage Pattern


Sources: src/Concerns/HandlesDatabases.php39-42

The setUpDatabaseRequirements Method

The setUpDatabaseRequirements() method orchestrates the complete database setup lifecycle. It manages the execution order of migrations, seeders, and cleanup hooks.

Method Signature


src/Concerns/HandlesDatabases.php47-55

Internal Workflow


Implementation Details

The method performs the following sequence:

  1. Calls defineDatabaseMigrations() to set up schema src/Concerns/HandlesDatabases.php49
  2. Registers destroyDatabaseMigrations() with beforeApplicationDestroyed() hook src/Concerns/HandlesDatabases.php50
  3. Executes the provided callback src/Concerns/HandlesDatabases.php52
  4. Calls defineDatabaseSeeders() to populate data src/Concerns/HandlesDatabases.php54

Usage Pattern


Sources: src/Concerns/HandlesDatabases.php47-55

Practical Testing Patterns

Pattern 1: Minimal Migration Setup

For simple tests that only need a basic schema:


Pattern 2: With Seeders

For tests requiring pre-populated data:


Pattern 3: Custom Setup Logic

For tests needing complex initialization:


Pattern 4: Manual Cleanup

For tests that need explicit cleanup:


Sources: src/Concerns/HandlesDatabases.php1-56

Database Configuration for Testing

The testbench uses SQLite in-memory database by default for fast, isolated testing. This configuration is defined in the workbench database config.

Default Configuration


workbench/config/database.php8-16

Configuration Table

SettingValuePurpose
driver'sqlite'Use SQLite database engine
database':memory:'Store database in memory (fast, isolated)
prefix''No table prefix
foreign_key_constraintstrueEnforce foreign key constraints

Sources: workbench/config/database.php1-38

Database Isolation Strategies

Strategy 1: In-Memory Database

The default SQLite in-memory configuration provides automatic isolation. Each test runs against a fresh database that exists only in memory and is destroyed when the test completes.

Advantages:

  • Fast execution
  • Complete isolation
  • No cleanup required

Limitations:

  • Lost between tests
  • Cannot inspect database after test failure

Strategy 2: Transaction Rollback

Wrap each test in a database transaction and roll back after the test:


Strategy 3: Manual Cleanup

Explicitly clean up data in destroyDatabaseMigrations():


Strategy 4: Database Refresh

Refresh the entire database between tests:


Sources: workbench/config/database.php10-15 src/Concerns/HandlesDatabases.php1-56

Integration with TestCase Lifecycle

The HandlesDatabases trait methods are automatically invoked by the TestCase lifecycle. The following diagram shows the complete integration.

TestCase Integration Diagram


The trait hooks into three key lifecycle points:

  1. Setup Phase: defineDatabaseMigrations() and defineDatabaseSeeders() are called during test setup
  2. Test Execution: Database is ready for test to use
  3. Teardown Phase: destroyDatabaseMigrations() is called via beforeApplicationDestroyed() hook

Sources: src/Concerns/HandlesDatabases.php47-55

Summary

The HandlesDatabases trait provides a structured approach to managing database state in tests through five lifecycle hooks. The default SQLite in-memory configuration ensures fast, isolated testing, while the trait's methods offer flexibility for complex database setup scenarios. By overriding the appropriate methods, tests can define migrations, seed data, handle refresh operations, and ensure proper cleanup while maintaining test isolation.

Sources: src/Concerns/HandlesDatabases.php1-56 workbench/config/database.php1-38

Refresh this wiki

On this page