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:
- The Events Calendar (6.10.2 or higher)
- The Events Calendar Pro (7.4.2 or higher)
- Event Tickets (5.19.3 or higher)
- Event Tickets Plus (6.2.0 or higher)
- The Events Calendar: Community Events (latest version)
- Note: Use only 'the-events-calendar-community-events' plugin, not the legacy 'community-events' plugin
- Spectra Pro (2.0.0 or higher)
- Premium Starter Templates (4.4.14 or higher)
- 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.pharexists inwordpress-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.ymlunder thewordpressservice:volumes: # ... other volumes ... - ./bin/wp-cli.phar:/usr/local/bin/wp - Restart containers if
docker-compose.ymlwas modified:# Run from wordpress-dev directory docker-compose down && docker-compose up -d - When running WP-CLI commands inside the container, use the
--allow-rootflag: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.phpas the bootstrap file. - Sets
backupGlobals="false"andprocessIsolation="false"globally to prevent issues with Closures and test environment state. - Important: Should not contain
<php><const .../></php>definitions for WordPress constants (likeABSPATH,DB_*,WP_TESTS_DIR), as these are handled by the bootstrap process and config files.
- Defines test suites (e.g.,
-
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_HOSTmust bedb. DB_PASSWORDshould usegetenv('DEV_DB_ROOT_PASSWORD')to read the root password from the.envfile (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.phpviadocker-compose.yml. Ensure the mount exists:
(Note:volumes: # ... other volumes ... - ./wp-tests-config.php:/var/www/html/wp-tests-config.php:cached:cachedflag might cause sync issues on some systems; remove if problems persist).
-
wordpress-dev/tests/bootstrap.php(Host file):- Locates the
wp-phpunitlibrary installed by Composer in thevendordirectory. - 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 towp-config.phpto skip its DB definitions. - Includes the Composer autoloader (
vendor/autoload.php). - Loads the plugin being tested (
hvac-community-events) usingtests_add_filter('muplugins_loaded', '_manually_load_hvac_plugin'). (Note: Manual loading of other dependencies like TEC viaplugins_loadedhook should remain commented out unless proven necessary). - Includes the main
wp-phpunittest library bootstrap:require $_tests_dir . '/includes/bootstrap.php';.
- Locates the
-
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 inif ( ! defined( 'WP_TESTS_RUNNING' ) ) { ... }to prevent conflicts withwp-tests-config.phpduring tests.
- The main database definitions (
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_Integrationis currently skipped (@group skip) due to unresolved environment conflicts related to serialization/initialization withinwp-phpunit. See Troubleshooting section.
- Note:
-
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_UnitTestCasewhich 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
-
PHPUnit:
wp-tests-config.php is missing!- Verify
wordpress-dev/wp-tests-config.phpexists on the host. - Verify the volume mount
- ./wp-tests-config.php:/var/www/html/wp-tests-config.phpexists indocker-compose.ymlfor thewordpressservice. - Verify
define( 'WP_TESTS_CONFIG_FILE_PATH', ABSPATH . 'wp-tests-config.php' );is present and correct intests/bootstrap.php. - Restart Docker containers (
docker-compose down && docker-compose up -d).
- Verify
-
PHPUnit:
Constant ... already definedWarnings- Ensure
<php><const .../></php>definitions are removed fromphpunit.xml.dist. - Ensure the
if ( ! defined( 'WP_TESTS_RUNNING' ) )check correctly wraps DB definitions inwordpress/wp-config.php. - Ensure
define( 'WP_TESTS_RUNNING', true );exists intests/bootstrap.phpbefore the main test bootstrap is required.
- Ensure
-
PHPUnit:
Undefined constant "ABSPATH"Fatal Error- Ensure
define( 'ABSPATH', '/var/www/html/' );exists inwp-tests-config.php. - Ensure
wp-tests-config.phpis correctly mounted and loaded (see point 1). - Ensure the main
wp-phpunit/includes/bootstrap.phploadswp-tests-config.phpbefore scripts needingABSPATH(likeinstall.phpor potentiallymock-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).
- Ensure
-
PHPUnit:
Access denied for user 'root'@'...' (using password: NO)- Ensure
DB_PASSWORDis correctly defined (hardcoded) inwp-tests-config.php. - Ensure the
if ( ! defined( 'WP_TESTS_RUNNING' ) )check correctly wraps DB definitions inwordpress/wp-config.php. - Ensure
wp-tests-config.phpis correctly mounted and loaded (see point 1). - Verify the test database (
wordpress_test) exists and the user (root) has privileges.
- Ensure
-
PHPUnit:
Could not find tests_dir/includes/functions.php- Ensure
composer installwas run successfully inwordpress-dev. - Verify the path calculation for
$_vendor_dirintests/bootstrap.phpis correct ($_vendor_dir = ABSPATH . 'vendor/wp-phpunit/wp-phpunit';). - Check permissions on the host
vendordirectory if issues persist. - Try removing the
:cachedflag from volume mounts indocker-compose.ymlif sync issues are suspected. Restart containers after changes.
- Ensure
-
PHPUnit:
Declaration of ... must be compatible with ...(): void- Add the
: voidreturn type hint to thesetUp()andtearDown()methods in your test class.
- Add the
-
WP-CLI:
executable file not found in $PATH- Ensure
wp-cli.pharis downloaded towordpress-dev/bin/. - Ensure the volume mount
- ./bin/wp-cli.phar:/usr/local/bin/wpexists indocker-compose.yml. - Ensure the host file
bin/wp-cli.pharhas execute permissions (chmod +x). - Restart Docker containers (
docker-compose down && docker-compose up -d).
- Ensure
-
WP-CLI/PHPUnit:
Allowed memory size exhausted- Increase
memory_limitinwordpress-dev/php.ini/custom.ini(e.g.,512M). - Ensure the volume mount
- ./php.ini/custom.ini:/usr/local/etc/php/conf.d/custom.iniis correct indocker-compose.yml. - Restart Docker containers (
docker-compose down && docker-compose up -d).
- Increase
-
E2E: Timeout waiting for element / 404 errors
-
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-phpunitbootstrap itself. - Solution:
- Ensure
backupGlobals="false"andprocessIsolation="false"are set in the main<phpunit>tag inphpunit.xml.dist. - If using mocking libraries like Brain Monkey, ensure
Monkey\setUp();andMonkey\tearDown();are called in your test class'ssetUp()andtearDown()methods. - If the error persists, it might indicate a deeper conflict within the
wp-phpunitbootstrap or WordPress core hooks introducing unserializable Closures. Investigate hooks added during bootstrap or test setup.
- Ensure
- 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.
- 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
-
PHPUnit:
Class ... not foundorNo tests executed!- Cause 1 (Missing Autoload): Composer's autoloader isn't configured to find your test classes. Ensure
composer.jsonhas anautoload-devsection mapping your test namespace (e.g.,"Tests\\": "tests/") and runcomposer dump-autoload. - Cause 2 (Namespace Conflict): The test class file is missing a
namespacedeclaration, or it's using a namespace (e.g.,namespace Tests\Integration;) that conflicts with thewp-phpunitenvironment's test discovery. Thewp-phpunitsetup 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.phpforclass TestClass). - Solution:
- Ensure
composer.jsonhas the correctautoload-devPSR-4 mapping and runcomposer dump-autoload. - For integration tests using
WP_UnitTestCase, define the test class in the global namespace (remove anynamespace ...;line) and ensure it extendsWP_UnitTestCase(no leading backslash needed). - Ensure the test filename matches the class name (e.g.,
TestMyFeature.phpforclass 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.
- Ensure
- Check container logs (
docker-compose logs wordpress,docker-compose logs nginx) for PHP or web server errors preventing the page from rendering.
- Cause 1 (Missing Autoload): Composer's autoloader isn't configured to find your test classes. Ensure
-
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).
-
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).
- Restart containers:
Last Updated: March 28, 2025