grazulex/laravel-tddraft

A powerful Laravel package that provides LaravelTddraft functionality with modern PHP 8.3+ features.

v1.0.0 2025-07-19 07:47 UTC

This package is auto-updated.

Last update: 2025-07-19 07:49:33 UTC


README

Laravel TDDraft

Set up Test-Driven Development environments in Laravel using Pest 3 with dedicated draft testing directories.

Latest Version Total Downloads License PHP Version Laravel Version Pest Version Code Style

Overview

Laravel TDDraft helps you practice Test-Driven Development by providing a structured approach to draft testing in Laravel applications. It creates a separate testing environment for experimental tests that won't interfere with your main test suite or CI pipeline.

TDDraft โ†’ CI Workflow

TDDraft to CI Test Promotion Workflow

Visual representation of the TDDraft workflow and promotion to CI test suite

The package enables a clean separation between experimental draft tests and production-ready CI tests, allowing you to practice TDD without affecting your deployment pipeline.

โœจ Features

  • ๐Ÿ”ง Five-command TDD workflow: The core innovation that enables true Test-Driven Development without CI interference
  • ๐Ÿ“‚ Creates dedicated tests/TDDraft/ directory for draft tests
  • โš™๏ธ Automatically configures PHPUnit and Pest to exclude drafts from main test runs
  • ๐Ÿงช Native Pest 3 support with proper test isolation
  • ๐Ÿ“‹ Automatic backup of configuration files before modification
  • ๐Ÿ”– Unique reference tracking for test promotion from draft to CI
  • ๐Ÿ“Š NEW: Test status tracking - Automatic tracking of test execution results and history
  • ๐ŸŽฏ Built for clean TDD workflow separation
  • ๐Ÿš€ Easy graduation path from draft tests to production test suite

๐Ÿ”ง The Five-Command TDD Workflow

Laravel TDDraft is built around a five-command workflow that enables true Test-Driven Development. This structured approach is the key to the project - it provides a complete TDD cycle from experimentation to production.

๐Ÿ”„ The Complete TDD Flow

The five commands work together in a specific sequence that mirrors the TDD Red-Green-Refactor cycle:

graph LR
    A[tdd:init] --> B[tdd:make]
    B --> C[tdd:test]
    C --> D{Test Passes?}
    D -->|No| E[Write Code]
    E --> C
    D -->|Yes| F[tdd:list]
    F --> G[tdd:promote]
    G --> H[CI Test Suite]
    
    style A fill:#ff9999
    style B fill:#ffcc99
    style C fill:#ffff99
    style F fill:#ccffcc
    style G fill:#99ccff
Loading

๐Ÿ“‹ Command Reference

Command Role in TDD Flow Description
tdd:init ๐Ÿ—๏ธ Setup Initialize TDDraft environment and configuration
tdd:make ๐Ÿงช Red Phase Create a new failing test with unique tracking
tdd:test ๐Ÿ”„ Red-Green Cycle Run and iterate on draft tests until they pass
tdd:list ๐Ÿ“‹ Review List and manage your draft tests before promotion
tdd:promote ๐Ÿš€ Graduate Move ready tests to production CI test suite

๐ŸŽฏ Why This Flow Matters

This five-command sequence is the core innovation of Laravel TDDraft. It solves the common TDD problems:

  1. tdd:init - Creates a separate space for experimental tests
  2. tdd:make - Enables rapid test creation without affecting CI
  3. tdd:test - Allows focused iteration on draft tests only
  4. tdd:list - Provides oversight of your TDD pipeline
  5. tdd:promote - Ensures only ready tests reach production

๐Ÿ” Complete Workflow Example

# 1. ๐Ÿ—๏ธ SETUP: Initialize your TDDraft environment (one-time)
php artisan tdd:init

# 2. ๐Ÿงช RED PHASE: Create failing tests for new features
php artisan tdd:make "User can register"
php artisan tdd:make "Password validation" --type=unit

# 3. ๐Ÿ”„ RED-GREEN CYCLE: Iterate until tests pass
php artisan tdd:test --filter="User can register"  # RED: Test fails
# Write minimal code to make test pass...
php artisan tdd:test --filter="User can register"  # GREEN: Test passes
# Refactor code...
php artisan tdd:test --filter="User can register"  # GREEN: Still passes

# 4. ๐Ÿ“‹ REVIEW: Check all draft tests before promotion
php artisan tdd:list --details

# 5. ๐Ÿš€ GRADUATE: Move ready tests to CI suite
php artisan tdd:promote tdd-20250718142530-Abc123

This workflow keeps your CI clean while enabling true TDD experimentation. Your main test suite never sees failing or experimental tests, but you can still practice proper Red-Green-Refactor cycles.

๐Ÿš€ Quick Start

1. Install the Package

composer require --dev grazulex/laravel-tddraft

2. Install Pest (Required)

๐Ÿ’ก Laravel TDDraft requires Pest v3.8 or higher:

composer require pestphp/pest --dev
php artisan pest:install

3. Publish Configuration

php artisan vendor:publish --tag=tddraft-config

4. Initialize TDDraft

php artisan tdd:init

This command will:

  • Create tests/TDDraft/ directory structure
  • Configure PHPUnit to separate TDDraft tests from main suite
  • Configure Pest to exclude TDDraft from default test runs
  • Optionally create example test files

๐Ÿ›  Usage

Create Draft Tests

Create new TDDraft tests with unique tracking:

# Create a feature test
php artisan tdd:make "User can register"

# Create a unit test  
php artisan tdd:make "Password validation" --type=unit

# Create test in a subdirectory
php artisan tdd:make "API authentication" --path=Auth/Api

# Create with custom class name
php artisan tdd:make "Complex scenario" --class=MyCustomTest

Write Draft Tests

The generated test files include unique references and proper grouping:

<?php

declare(strict_types=1);

/**
 * TDDraft Test: User can register
 * 
 * Reference: tdd-20250718142530-Abc123
 * Type: feature
 * Created: 2025-07-18 14:25:30
 */

it('user can register', function (): void {
    // TODO: Implement your test scenario here
    $response = $this->post('/register', [
        'name' => 'John Doe',
        'email' => 'john@example.com',
        'password' => 'password',
        'password_confirmation' => 'password',
    ]);

    $response->assertStatus(201);
    $this->assertDatabaseHas('users', [
        'email' => 'john@example.com',
    ]);
})
->group('tddraft', 'feature', 'tdd-20250718142530-Abc123')
->todo('Implement the test scenario for: user can register');

Run Tests Separately

# Run only main tests (excludes TDDraft)
pest

# Run only TDDraft tests (with automatic status tracking!)
php artisan tdd:test

# Run TDDraft tests with options
php artisan tdd:test --filter="user registration"
php artisan tdd:test --coverage
php artisan tdd:test --parallel
php artisan tdd:test --stop-on-failure

# Filter by type
pest --testsuite=tddraft --group=feature
pest --testsuite=tddraft --group=unit

# Filter by specific reference
pest --testsuite=tddraft --group=tdd-20250718142530-Abc123

# Alternative: use pest directly
pest --testsuite=tddraft

# Run all tests including TDDraft
pest --testsuite=default,tddraft

Test Status Tracking (NEW)

Laravel TDDraft now automatically tracks your test execution results:

# Run tests with automatic status tracking
php artisan tdd:test

# Status is automatically saved to tests/TDDraft/.status.json
# Each test result is linked to its unique reference for precise tracking

Status tracking provides:

  • Automatic recording of test results (passed/failed/error/skipped)
  • Historical tracking of status changes over time
  • Reference-based linking for audit trails
  • JSON storage for easy integration with other tools

List and Manage Tests

Use the tdd:list command to view and manage your draft tests:

# List all draft tests
php artisan tdd:list

# Show detailed information
php artisan tdd:list --details

# Filter by test type
php artisan tdd:list --type=feature
php artisan tdd:list --type=unit

# Filter by directory path
php artisan tdd:list --path=Auth

Example output:

๐Ÿ“‹ TDDraft Tests List
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Reference                โ”‚ Name                                    โ”‚ Type    โ”‚ Status      โ”‚ File                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ tdd-20250718142530-Abc123โ”‚ User can register                       โ”‚ feature โ”‚ โœ… Passed   โ”‚ UserCanRegisterTest.php โ”‚
โ”‚ tdd-20250718141045-Def456โ”‚ Password validation                     โ”‚ unit    โ”‚ โŒ Failed   โ”‚ PasswordValidationTest.phpโ”‚
โ”‚ tdd-20250718140012-Ghi789โ”‚ API authentication                      โ”‚ feature โ”‚ โ“ Unknown  โ”‚ Auth/ApiAuthTest.php    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“Š Total: 3 draft test(s)

๐Ÿ’ก Tips:
  โ€ข Run specific test: php artisan tdd:test --filter="<reference>"
  โ€ข Run by type: php artisan tdd:test --filter="feature"
  โ€ข Promote draft: php artisan tdd:promote <reference>

Graduate Tests

When your draft test is ready for production, you have two options for promoting it to your main test suite:

Option 1: Automated Promotion (Recommended)

Use the tdd:promote command with the unique reference for automated promotion:

# Basic promotion (promotes to Feature directory by default)
php artisan tdd:promote tdd-20250718142530-Abc123

# Promote to specific directory
php artisan tdd:promote tdd-20250718142530-Abc123 --target=Unit

# Promote with custom file name
php artisan tdd:promote tdd-20250718142530-Abc123 --new-file=UserRegistrationTest

# Append to existing test file
php artisan tdd:promote tdd-20250718142530-Abc123 --file=ExistingTest.php

# Keep the original draft file
php artisan tdd:promote tdd-20250718142530-Abc123 --keep-draft

# Force overwrite without confirmation
php artisan tdd:promote tdd-20250718142530-Abc123 --force

Option 2: Manual Promotion

For manual control, you can still promote tests manually:

# Step 1: Note the unique reference from your test file
# Example test header:
# /**
#  * TDDraft Test: User can register
#  * Reference: tdd-20250718142530-Abc123
#  * Type: feature
#  * Created: 2025-07-18 14:25:30
#  */

# Step 2: Move the test file to your main test suite
mv tests/TDDraft/UserCanRegisterTest.php tests/Feature/Auth/UserRegistrationTest.php

# Step 3: Update the test groups (remove 'tddraft', keep reference for tracking)
# Change: ->group('tddraft', 'feature', 'tdd-20250718142530-Abc123')
# To:     ->group('feature', 'tdd-20250718142530-Abc123')

# Step 4: Run the promoted test to ensure it works in main suite
pest tests/Feature/Auth/UserRegistrationTest.php

# Step 5: Run full test suite to verify no conflicts
pest

Tracking Test Lineage

The unique reference system allows you to:

  • Track which tests originated from TDDraft
  • Monitor test evolution from draft to production
  • Maintain audit trail for compliance
  • Link CI failures back to original draft intent

๐Ÿ“ Configuration

The package configuration is published to config/tddraft.php:

return [
    /**
     * Test status tracking configuration
     *
     * NEW: Controls how test execution results are tracked and persisted.
     */
    'status_tracking' => [
        // Enable or disable status tracking
        'enabled' => env('LARAVEL_TDDRAFT_STATUS_TRACKING_ENABLED', true),

        // File path where test statuses are saved (relative to Laravel base path)
        'file_path' => env('LARAVEL_TDDRAFT_STATUS_FILE', 'tests/TDDraft/.status.json'),

        // Keep history of status changes for each test
        'track_history' => env('LARAVEL_TDDRAFT_TRACK_HISTORY', true),

        // Maximum number of history entries to keep per test
        'max_history_entries' => env('LARAVEL_TDDRAFT_MAX_HISTORY', 50),
    ],
];

Environment Variables:

# Enable/disable status tracking
LARAVEL_TDDRAFT_STATUS_TRACKING_ENABLED=true

# Configure status file location
LARAVEL_TDDRAFT_STATUS_FILE=tests/TDDraft/.status.json

# Control history tracking
LARAVEL_TDDRAFT_TRACK_HISTORY=true
LARAVEL_TDDRAFT_MAX_HISTORY=50

๐Ÿงช Example Draft Test

<?php

declare(strict_types=1);

it('should fail initially - this is normal for TDDraft', function (): void {
    // This test intentionally fails to demonstrate the TDD "red" phase
    expect(false)->toBeTrue('This draft needs implementation!');
})->group('tddraft', 'feature', 'example-red-phase');

it('can be promoted when ready', function (): void {
    // When this passes, you can promote it to your main test suite
    expect(true)->toBeTrue();
})->group('tddraft', 'feature', 'example-green-phase');

๐Ÿ“š Documentation

For comprehensive documentation, see the docs/ directory:

๐Ÿ”ง Requirements

  • PHP 8.3+
  • Laravel 12.19+
  • Pest 3.8+

๐Ÿค Contributing

Please see CONTRIBUTING.md for details on how to contribute to this project.

๐Ÿ“„ License

This package is open-source software licensed under the MIT license.

Made with โค๏ธ for the Laravel and Pest community