authlab/fluent-tester

WordPress testing framework for plugin and theme

dev-master / 2.0.x-dev 2025-09-12 17:24 UTC

This package is auto-updated.

Last update: 2025-09-12 17:25:10 UTC


README

Modern WordPress testing framework built on Pest and wp-browser for comprehensive WordPress plugin testing.

Features

  • ๐Ÿงช Pest PHP - Modern, expressive testing syntax
  • ๐ŸŒ wp-browser - Complete WordPress testing environment
  • ๐Ÿ”„ Codeception Integration - Powerful browser automation and testing modules
  • ๐ŸŽฏ Multi-layer Testing - Unit, Integration, Functional & Acceptance tests
  • ๐Ÿš€ WordPress-specific - Built specifically for WordPress plugin development
  • โšก SQLite/MySQL Support - Choose your database backend
  • ๐Ÿ“ฆ Easy Setup - One-command environment initialization
  • ๐Ÿ”ง CI/CD Ready - GitHub Actions and other CI platforms

Requirements

  • PHP 8.3 or higher
  • Composer
  • WordPress development environment
  • Git (for dependency installation)

Installation

Install via Composer as a development dependency:

composer require --dev authlab/fluent-tester

The post-install script will automatically:

  1. Run Codeception bootstrap
  2. Execute the initialization script to set up WordPress test environment

Installing in WordPress projects with composer platform.php pinned (e.g., 7.4)

Some WordPress projects set composer config platform.php 7.4 for production compatibility. Since Fluent Tester requires PHP 8.1+, Composer may refuse installation. Use one of these approaches:

Option A โ€” temporarily bump platform (preferred)

composer config platform.php 8.3
composer require --dev authlab/fluent-tester
# Optionally revert later:
# composer config --unset platform.php

Option B โ€” one-off install ignoring platform

composer require --dev authlab/fluent-tester --ignore-platform-req=php

Option C โ€” developer-only composer file (kept out of VCS)

{
  "config": { "platform": { "php": "8.3" } }
}

Install using:

COMPOSER=composer.local.json composer require --dev authlab/fluent-tester

Be sure to git-ignore composer.local.json.

Note: Regardless of composer configuration, the runtime PHP used to execute the test suite must be PHP 8.1+.

Installing in WordPress projects with composer platform.php pinned (e.g., 7.4)

Some WordPress projects set composer config platform.php 7.4 for production compatibility. Since Fluent Tester requires PHP 8.1+, Composer may refuse installation. Use one of these approaches:

Option A โ€” temporarily bump platform (preferred)

composer config platform.php 8.3
composer require --dev authlab/fluent-tester
# Optionally revert later:
# composer config --unset platform.php

Option B โ€” one-off install ignoring platform

composer require --dev authlab/fluent-tester --ignore-platform-req=php

Option C โ€” developer-only composer file (kept out of VCS)

{
  "config": { "platform": { "php": "8.3" } }
}

Install using:

COMPOSER=composer.local.json composer require --dev authlab/fluent-tester

Be sure to git-ignore composer.local.json.

Note: Regardless of composer configuration, the runtime PHP used to execute the test suite must be PHP 8.1+.

Quick Start

  1. Configure Environment

    Copy the environment template and configure for your setup:

    cp .env.testing .env
    # Edit .env with your WordPress and database settings
  2. Initialize Test Environment

    ./vendor/bin/fluent-tester init
    # or
    composer init
  3. Run Tests

    # Run all tests with Pest
    composer test
    
    # Run specific test suites
    composer test-unit          # Unit tests (fast)
    composer test-integration   # Integration tests with WordPress
    composer test-functional    # Functional tests with browser

    Versions and Stability

    If you see "Could not find a version of package authlab/fluent-tester matching your minimum-stability (stable)":

    • Preferred (after a release tag is published):
      composer require --dev authlab/fluent-tester:^2.0
    • Until a tag exists (use dev stability explicitly):
      # Option 1: require dev branch with alias
      composer require --dev "authlab/fluent-tester:dev-master as 2.0.x-dev"
      # Option 2: use stability flag
      composer require --dev authlab/fluent-tester:^2.0@dev
      # Or explicitly require the branch
      composer require --dev authlab/fluent-tester:dev-master

    Branch naming note:

    • If the repository default branch is "master", use dev-master
    • If the repository default branch is "main", use dev-main

    Composer allow-plugins (non-interactive):

    • Composer may prompt to allow pestphp/pest-plugin. To avoid prompts (e.g., CI), configure in your project:
      composer config allow-plugins.pestphp/pest-plugin true
      composer config allow-plugins.codeception/c3 true
      Or add to your root composer.json:
      {
        "config": {
          "allow-plugins": {
            "pestphp/pest-plugin": true,
            "codeception/c3": true
          }
        }
      }

    Testing Architecture

Test Types

  • Unit Tests (tests/Unit/) - Pure PHP logic testing with WPLoader
  • Integration Tests (tests/Integration/) - WordPress integration with database
  • Functional Tests (tests/Functional/) - Browser-based WordPress testing
  • Acceptance Tests (tests/Acceptance/) - Full end-to-end user scenarios

Test Syntax

Write expressive tests using Pest PHP syntax:

<?php

test('fluent cart creates new cart', function () {
    $cart = FluentCart::create();
    
    expect($cart)
        ->toBeInstanceOf(FluentCart::class)
        ->and($cart->getId())
        ->toBeGreaterThan(0);
});

test('cart can add products', function () {
    $cart = FluentCart::create();
    $product = ['id' => 123, 'name' => 'Test Product', 'price' => 29.99];
    
    $cart->addProduct($product);
    
    expect($cart->getProducts())
        ->toHaveCount(1)
        ->and($cart->getTotal())
        ->toBe(29.99);
});

it('validates product data', function () {
    $cart = FluentCart::create();
    
    expect(fn() => $cart->addProduct(['invalid' => 'data']))
        ->toThrow(InvalidProductException::class);
});

WordPress-Specific Testing

<?php

test('plugin activates successfully', function () {
    activate_plugin_for_test('fluent-cart/fluent-cart.php');
    
    expect(is_plugin_active('fluent-cart/fluent-cart.php'))
        ->toBeTrue();
});

test('creates database tables on activation', function () {
    global $wpdb;
    
    // Plugin activation creates tables
    FluentCart::install();
    
    $table = $wpdb->prefix . 'fluent_carts';
    expect($wpdb->get_var("SHOW TABLES LIKE '$table'"))
        ->toBe($table);
});

test('registers REST API endpoints', function () {
    $routes = rest_get_server()->get_routes();
    
    expect($routes)
        ->toHaveKey('/fluent-cart/v1')
        ->and($routes['/fluent-cart/v1/carts'])
        ->not->toBeEmpty();
});

Configuration

Environment Variables (.env)

# WordPress Configuration
WP_ROOT_FOLDER=/path/to/wordpress
WP_URL=http://localhost:8000
WP_ADMIN_USERNAME=admin
WP_ADMIN_PASSWORD=admin

# Database (SQLite - default)
DB_ENGINE=sqlite
TEST_DB_NAME=:memory:

# Database (MySQL - alternative)
# DB_ENGINE=mysql
# TEST_DB_NAME=wp_test
# TEST_DB_USER=root
# TEST_DB_PASSWORD=password
# TEST_DB_HOST=localhost

# Plugin Configuration  
FLUENT_CART_PATH=../fluent-cart

Codeception Configuration

The framework uses codeception.yml for wp-browser configuration:

  • WPDb - Database operations and fixtures
  • WPBrowser - WordPress admin and frontend testing
  • WPLoader - WordPress core loading for integration tests
  • WPFilesystem - File and directory operations

Advanced Usage

Custom Test Helpers

Create WordPress-specific helpers in your tests:

<?php

// tests/Pest.php
function createTestCart(array $products = []): FluentCart 
{
    $cart = FluentCart::create();
    
    foreach ($products as $product) {
        $cart->addProduct($product);
    }
    
    return $cart;
}

function createTestUser(string $role = 'customer'): WP_User
{
    return wp_insert_user([
        'user_login' => 'test_' . uniqid(),
        'user_pass' => 'password',
        'user_email' => 'test@example.com',
        'role' => $role
    ]);
}

Database Testing

<?php

test('cart persists to database', function () {
    $cart = createTestCart([
        ['id' => 1, 'name' => 'Product 1', 'price' => 10.00]
    ]);
    
    $cart->save();
    
    // Test database persistence
    $saved = FluentCart::find($cart->getId());
    expect($saved->getProducts())->toHaveCount(1);
});

Browser Testing

<?php

test('user can add product to cart via frontend', function () {
    // This would use wp-browser's functional testing
    $I = new FunctionalTester();
    
    $I->amOnPage('/product/test-product');
    $I->click('Add to Cart');
    $I->see('Product added to cart');
    
    $I->amOnPage('/cart');
    $I->see('Test Product');
});

CI/CD Integration

GitHub Actions Example

name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.3'
        extensions: mbstring, xml, sqlite3
        
    - name: Install dependencies
      run: composer install
      
    - name: Run tests
      run: composer test

Migration from v1.x

If upgrading from the PHPUnit-based v1.x:

  1. Dependencies: The new version uses Pest + wp-browser instead of PHPUnit + WP-CLI
  2. Configuration: Replace phpunit.xml with tests/Pest.php and codeception.yml
  3. Test Structure: Tests can use Pest syntax but PHPUnit syntax still works
  4. Environment: Use .env configuration instead of XML-based setup

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for new features
  4. Ensure all tests pass: composer test
  5. Submit a pull request

License

GPL-2.0-or-later - see LICENSE file for details.

Support