294 lines
No EOL
17 KiB
Markdown
294 lines
No EOL
17 KiB
Markdown
# 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:
|
|
```bash
|
|
# 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:
|
|
```bash
|
|
# 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:
|
|
```bash
|
|
# 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:
|
|
```yaml
|
|
volumes:
|
|
# ... other volumes ...
|
|
- ./bin/wp-cli.phar:/usr/local/bin/wp
|
|
```
|
|
- **Restart containers** if `docker-compose.yml` was modified:
|
|
```bash
|
|
# 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:
|
|
```bash
|
|
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:
|
|
```yaml
|
|
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.
|
|
```bash
|
|
# 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:
|
|
```bash
|
|
# 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.
|
|
|
|
```bash
|
|
# 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**
|
|
|
|
|
|
11. **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.
|
|
|
|
|
|
12. **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.
|
|
|
|
|
|
13. **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).
|
|
|
|
10. **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* |