upskill-event-manager/docs/archive/testing.md

17 KiB

Testing Guide

Status: Active/Authoritative Last Updated: April 5, 2025 Scope: Testing the HVAC Community Events plugin

This guide covers setting up the test environment and running tests for the HVAC Community Events plugin using our unified test suite within the Docker environment.

Test Environment Requirements

Prerequisites

  • Docker and Docker Compose
  • Git
  • Node.js and npm (for E2E tests)
  • Composer

Required WordPress Plugins

The test environment requires specific plugins with their minimum versions. These plugins are included in the database/files restored by the setup-from-backup.sh script and should not be updated manually during testing unless specifically testing updates:

  1. The Events Calendar (6.10.2 or higher)
  2. The Events Calendar Pro (7.4.2 or higher)
  3. Event Tickets (5.19.3 or higher)
  4. Event Tickets Plus (6.2.0 or higher)
  5. The Events Calendar: Community Events (latest version)
    • Note: Use only 'the-events-calendar-community-events' plugin, not the legacy 'community-events' plugin
  6. Spectra Pro (2.0.0 or higher)
  7. Premium Starter Templates (4.4.14 or higher)
  8. Essential Blocks (5.3.2 or higher)

Important:

  • Do not update plugins as part of standard testing.
  • Plugin updates should be tested separately in a dedicated environment or branch.

Test Environment Setup

The test environment relies heavily on the Docker setup defined in docker-compose.yml and configuration files mounted via volumes.

1. Initial Environment Setup

Ensure the main development environment is set up correctly using the backup restoration script:

# Run from wordpress-dev directory
./bin/setup-from-backup.sh

# Verify basic setup (optional but recommended)
./bin/verify-simple.sh

2. Install Dependencies (Composer & NPM)

Install PHP and Node.js dependencies:

# Run from wordpress-dev directory
composer install
npm install

This installs necessary libraries (PHPUnit, Playwright, etc.) into the ./vendor and node_modules directories, which are mounted into the container. Ensure @playwright/test is listed in package.json devDependencies. Ensure composer.json includes an autoload-dev section for the tests/ directory.

3. Configure PHP Memory Limit

Run from wordpress-dev directory

composer install

This installs necessary libraries into the `./vendor` directory, which is mounted into the container.

### 3. Configure PHP Memory Limit
The default PHP memory limit might be too low. Ensure it's increased:
- Edit the host file: `wordpress-dev/php.ini/custom.ini`
- Set `memory_limit = 512M` (or higher if needed).
- **Crucially, restart the Docker containers** after modifying this file:
  ```bash
  # Run from wordpress-dev directory
  docker-compose down && docker-compose up -d

4. Configure WP-CLI

WP-CLI is required for some test setup steps and verification. It's made available via a volume mount.

  • Ensure wp-cli.phar exists in wordpress-dev/bin/. If not, download it:
    # Run from wordpress-dev directory
    curl -o bin/wp-cli.phar https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
    chmod +x bin/wp-cli.phar
    
  • Ensure the following volume mount exists in docker-compose.yml under the wordpress service:
    volumes:
      # ... other volumes ...
      - ./bin/wp-cli.phar:/usr/local/bin/wp
    
  • Restart containers if docker-compose.yml was modified:
    # Run from wordpress-dev directory
    docker-compose down && docker-compose up -d
    
  • When running WP-CLI commands inside the container, use the --allow-root flag:
    docker-compose exec wordpress wp plugin list --allow-root
    

5. Configure PHPUnit Test Environment

The PHPUnit environment requires several configuration files to work correctly with WordPress within Docker:

  • wordpress-dev/phpunit.xml.dist:

    • Defines test suites (e.g., unit, integration).
    • Specifies tests/bootstrap.php as the bootstrap file.
    • Sets backupGlobals="false" and processIsolation="false" globally to prevent issues with Closures and test environment state.
    • Important: Should not contain <php><const .../></php> definitions for WordPress constants (like ABSPATH, DB_*, WP_TESTS_DIR), as these are handled by the bootstrap process and config files.
  • wordpress-dev/wp-tests-config.php (Host file):

    • This file must exist on the host.
    • It defines the test database credentials (DB_NAME, DB_USER, DB_HOST). DB_HOST must be db.
    • DB_PASSWORD should use getenv('DEV_DB_ROOT_PASSWORD') to read the root password from the .env file (sourced by the test runner script).
    • It must define define( 'ABSPATH', '/var/www/html/' ); because the test installation script needs it.
    • It should not define WP_TESTS_CONFIG_FILE_PATH.
    • This file is mounted into the container at /var/www/html/wp-tests-config.php via docker-compose.yml. Ensure the mount exists:
      volumes:
        # ... other volumes ...
        - ./wp-tests-config.php:/var/www/html/wp-tests-config.php:cached
      
      (Note: :cached flag might cause sync issues on some systems; remove if problems persist).
  • wordpress-dev/tests/bootstrap.php (Host file):

    • Locates the wp-phpunit library installed by Composer in the vendor directory.
    • Defines define( 'WP_TESTS_CONFIG_FILE_PATH', '/var/www/html/wp-tests-config.php' ); (using absolute path).
    • Defines define( 'WP_TESTS_RUNNING', true ); to signal to wp-config.php to skip its DB definitions.
    • Includes the Composer autoloader (vendor/autoload.php).
    • Loads the plugin being tested (hvac-community-events) using tests_add_filter('muplugins_loaded', '_manually_load_hvac_plugin'). (Note: Manual loading of other dependencies like TEC via plugins_loaded hook should remain commented out unless proven necessary).
    • Includes the main wp-phpunit test library bootstrap: require $_tests_dir . '/includes/bootstrap.php';.
  • wordpress-dev/wordpress/wp-config.php (Host file, mounted into container):

    • The main database definitions (DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, DB_CHARSET, DB_COLLATE) must be wrapped in if ( ! defined( 'WP_TESTS_RUNNING' ) ) { ... } to prevent conflicts with wp-tests-config.php during tests.

6. Verify Test Database

Ensure the test database (wordpress_test) exists and the user (root) has access.

# Run from wordpress-dev directory
# Create DB if it doesn't exist (uses password from .env)
docker-compose exec db mysql -uroot -p"${DEV_DB_ROOT_PASSWORD}" -e "CREATE DATABASE IF NOT EXISTS wordpress_test;"
# Grant privileges (optional, root usually has them)
# docker-compose exec db mysql -uroot -p"${DEV_DB_ROOT_PASSWORD}" -e "GRANT ALL PRIVILEGES ON wordpress_test.* TO 'root'@'%';"

Important: Before running tests, ensure dependencies are installed (composer install, npm install) and the environment is prepared using ./bin/setup-test-env.sh.

7. Activate Plugin Under Test

Ensure the hvac-community-events plugin is active for integration and E2E tests:

# Run from wordpress-dev directory
docker-compose exec wordpress wp plugin activate hvac-community-events --allow-root

Running Tests

Use the run-tests.sh script located in the wordpress-dev/bin directory.

# Run all test suites (Unit, Integration, E2E)
./bin/run-tests.sh

# Run only Unit tests
./bin/run-tests.sh --unit

# Run only Integration tests
./bin/run-tests.sh --integration

# Run only E2E tests
./bin/run-tests.sh --e2e

# Run specific E2E test suite (e.g., login tests tagged with @login)
./bin/run-tests.sh --login

# Run with debug output
./bin/run-tests.sh --debug

Note: The script is configured to exit immediately if Unit or Integration tests fail.

Test Types

Unit Tests

  • Location: wordpress-dev/tests/unit/

    • Note: Test_HVAC_Profile_Integration is currently skipped (@group skip) due to unresolved environment conflicts related to serialization/initialization within wp-phpunit. See Troubleshooting section.
  • Purpose: Test individual PHP classes and functions in isolation.

  • Environment: Minimal dependencies, does not require a fully bootstrapped WordPress environment for most tests (though uses WP_UnitTestCase which provides some WP functions).

  • Execution: Fast.

Integration Tests

  • Location: wordpress-dev/tests/integration/
  • Purpose: Test functionality that requires interaction with WordPress core, the database, or other plugins (e.g., hooks, filters, options, user roles, CPTs).
  • Environment: Requires the WordPress test environment loaded via wp-phpunit.
  • Execution: Slower than unit tests.

E2E (End-to-End) Tests

  • Location: wordpress-dev/tests/e2e/
  • Framework: Playwright
  • Purpose: Simulate real user interactions in a browser, testing complete user flows from the frontend.
  • Environment: Requires the full Docker environment (WordPress, Nginx, DB) to be running and accessible via http://localhost:8080.
  • Execution: Slowest test type.

Writing Tests

Refer to PHPUnit and Playwright documentation for detailed syntax.

Best Practices

  • One test class per code class/component/feature.
  • Use descriptive test method names (e.g., test_login_redirects_trainer_to_dashboard).
  • Test both expected outcomes (happy path) and error conditions (negative path).
  • Make tests independent; the outcome of one test should not affect another.
  • Clean up any created data (posts, users, options) in tearDown() methods or use WP test factories.

Troubleshooting Common Issues

  1. PHPUnit: wp-tests-config.php is missing!

    • Verify wordpress-dev/wp-tests-config.php exists on the host.
    • Verify the volume mount - ./wp-tests-config.php:/var/www/html/wp-tests-config.php exists in docker-compose.yml for the wordpress service.
    • Verify define( 'WP_TESTS_CONFIG_FILE_PATH', ABSPATH . 'wp-tests-config.php' ); is present and correct in tests/bootstrap.php.
    • Restart Docker containers (docker-compose down && docker-compose up -d).
  2. PHPUnit: Constant ... already defined Warnings

    • Ensure <php><const .../></php> definitions are removed from phpunit.xml.dist.
    • Ensure the if ( ! defined( 'WP_TESTS_RUNNING' ) ) check correctly wraps DB definitions in wordpress/wp-config.php.
    • Ensure define( 'WP_TESTS_RUNNING', true ); exists in tests/bootstrap.php before the main test bootstrap is required.
  3. PHPUnit: Undefined constant "ABSPATH" Fatal Error

    • Ensure define( 'ABSPATH', '/var/www/html/' ); exists in wp-tests-config.php.
    • Ensure wp-tests-config.php is correctly mounted and loaded (see point 1).
    • Ensure the main wp-phpunit/includes/bootstrap.php loads wp-tests-config.php before scripts needing ABSPATH (like install.php or potentially mock-mailer.php) are called. (Self-correction: We fixed mock-mailer by defining ABSPATH early in our bootstrap, but install.php needs it from wp-tests-config).
  4. PHPUnit: Access denied for user 'root'@'...' (using password: NO)

    • Ensure DB_PASSWORD is correctly defined (hardcoded) in wp-tests-config.php.
    • Ensure the if ( ! defined( 'WP_TESTS_RUNNING' ) ) check correctly wraps DB definitions in wordpress/wp-config.php.
    • Ensure wp-tests-config.php is correctly mounted and loaded (see point 1).
    • Verify the test database (wordpress_test) exists and the user (root) has privileges.
  5. PHPUnit: Could not find tests_dir/includes/functions.php

    • Ensure composer install was run successfully in wordpress-dev.
    • Verify the path calculation for $_vendor_dir in tests/bootstrap.php is correct ($_vendor_dir = ABSPATH . 'vendor/wp-phpunit/wp-phpunit';).
    • Check permissions on the host vendor directory if issues persist.
    • Try removing the :cached flag from volume mounts in docker-compose.yml if sync issues are suspected. Restart containers after changes.
  6. PHPUnit: Declaration of ... must be compatible with ...(): void

    • Add the : void return type hint to the setUp() and tearDown() methods in your test class.
  7. WP-CLI: executable file not found in $PATH

    • Ensure wp-cli.phar is downloaded to wordpress-dev/bin/.
    • Ensure the volume mount - ./bin/wp-cli.phar:/usr/local/bin/wp exists in docker-compose.yml.
    • Ensure the host file bin/wp-cli.phar has execute permissions (chmod +x).
    • Restart Docker containers (docker-compose down && docker-compose up -d).
  8. WP-CLI/PHPUnit: Allowed memory size exhausted

    • Increase memory_limit in wordpress-dev/php.ini/custom.ini (e.g., 512M).
    • Ensure the volume mount - ./php.ini/custom.ini:/usr/local/etc/php/conf.d/custom.ini is correct in docker-compose.yml.
    • Restart Docker containers (docker-compose down && docker-compose up -d).
  9. E2E: Timeout waiting for element / 404 errors

  10. PHPUnit: Serialization of 'Closure' is not allowed

    • Cause: This error occurs when PHPUnit tries to serialize the test environment state (e.g., for process isolation or global state backup) and encounters a Closure (anonymous function), which PHP cannot serialize. This often happens with mocking libraries (like Brain Monkey) or potentially within the wp-phpunit bootstrap itself.
    • Solution:
      • Ensure backupGlobals="false" and processIsolation="false" are set in the main <phpunit> tag in phpunit.xml.dist.
      • If using mocking libraries like Brain Monkey, ensure Monkey\setUp(); and Monkey\tearDown(); are called in your test class's setUp() and tearDown() methods.
      • If the error persists, it might indicate a deeper conflict within the wp-phpunit bootstrap or WordPress core hooks introducing unserializable Closures. Investigate hooks added during bootstrap or test setup.
    • Verify the plugin under test (hvac-community-events) is active (docker-compose exec wordpress wp plugin is-active hvac-community-events --allow-root). Activate if needed.
    • Verify the URL/slug used in page.goto() in the Playwright test matches the actual page slug in WordPress containing the shortcode or element.
    • Verify the element selector used in the test matches the actual element ID/class/attribute in the rendered HTML.
  11. PHPUnit: Class ... not found or No tests executed!

    • Cause 1 (Missing Autoload): Composer's autoloader isn't configured to find your test classes. Ensure composer.json has an autoload-dev section mapping your test namespace (e.g., "Tests\\": "tests/") and run composer dump-autoload.
    • Cause 2 (Namespace Conflict): The test class file is missing a namespace declaration, or it's using a namespace (e.g., namespace Tests\Integration;) that conflicts with the wp-phpunit environment's test discovery. The wp-phpunit setup seems to work more reliably with test classes in the global namespace.
    • Cause 3 (Filename Mismatch): PHPUnit might sometimes struggle if the filename doesn't match the class name convention (e.g., TestClass.php for class TestClass).
    • Solution:
      • Ensure composer.json has the correct autoload-dev PSR-4 mapping and run composer dump-autoload.
      • For integration tests using WP_UnitTestCase, define the test class in the global namespace (remove any namespace ...; line) and ensure it extends WP_UnitTestCase (no leading backslash needed).
      • Ensure the test filename matches the class name (e.g., TestMyFeature.php for class TestMyFeature).
      • Verify the class name and method names are correct (case-sensitive, methods start with test).
      • Check for subtle PHP syntax errors in the test file.
    • Check container logs (docker-compose logs wordpress, docker-compose logs nginx) for PHP or web server errors preventing the page from rendering.
  12. E2E: 404 Error for Specific JS File (e.g., php-date-formatter.js)

    • Cause: The specific JavaScript file required by a third-party plugin (like The Events Calendar: Community Events) is missing from the plugin's installed files within the Docker container, even after syncing from production.
    • Diagnosis: Use docker-compose exec -T wordpress find /path/to/plugin/ -name 'filename.js' to confirm the file is missing.
    • Solution/Workaround:
      • Verify the expected plugin version is installed.
      • Attempt a clean reinstall of the specific third-party plugin.
      • If the file is consistently missing, modify the E2E test to skip steps that depend on the missing script's functionality (e.g., avoid interacting with a date picker or rich text editor initialized by that script).
  13. General Docker Issues:

    • Restart containers: docker-compose down && docker-compose up -d
    • Prune system: docker system prune -a (Use with caution, removes unused images/volumes/networks)
    • Check Docker Desktop/Engine resource allocation (Memory, CPU).

Last Updated: March 28, 2025