Overview
Visual Portfolio uses a comprehensive testing strategy to ensure code quality and prevent regressions. The testing suite includes PHP unit tests and end-to-end (E2E) browser tests.Test Suite Components
- PHP Unit Tests: Test PHP classes and functions in isolation
- E2E Tests: Test complete user workflows in a real browser using Playwright
- WordPress Environment: Docker-based WordPress instance for testing
Quick Start
Run all tests:- All linters (
npm run lint) - PHP unit tests (
npm run test:unit:php) - Playwright E2E tests (
npm run test:e2e)
WordPress Environment Setup
The plugin uses@wordpress/env (wp-env) to create a Docker-based WordPress environment for testing.
Starting the Environment
- WordPress Site:
http://localhost:8889 - Admin:
http://localhost:8889/wp-admin- Username:
admin - Password:
password
- Username:
Environment Configuration
The wp-env configuration is defined in.wp-env.json:
PHP Unit Tests
Running PHP Tests
Test Structure
PHP tests are located intests/phpunit/unit/:
Writing PHP Unit Tests
Create test files following WordPress test conventions:PHPUnit Configuration
Configuration is defined inphpunit.xml.dist (located in the project root):
- Test suite:
tests/phpunit/unit/ - Bootstrap file:
tests/phpunit/bootstrap.php - WordPress test library integration
PHP Testing Dependencies
Fromcomposer.json:
End-to-End Tests
Running E2E Tests
Playwright Configuration
E2E tests use Playwright with WordPress-specific utilities. Configuration is intests/e2e/playwright.config.js:
E2E Test Structure
Writing E2E Tests
Create test files intests/e2e/specs/:
E2E Test Utilities
Helper functions are provided intests/e2e/utils/:
- create-posts.js: Create test posts with images
- create-pattern.js: Create WordPress block patterns
- delete-all-portfolio.js: Clean up portfolio items
- delete-all-saved-layouts.js: Clean up saved layouts
- get-wordpress-images.js: Get test images from WordPress
- open-published-page.js: Navigate to published content
- find-async-sequential.js: Async array utilities
Test Fixtures
Test data is stored intests/fixtures/:
- images.json: Test image metadata
- image-*.: Test images in various formats and sizes
- archive/: Archive-related test data and expected outputs
- click-actions/: Click action test fixtures
Browser Testing
Playwright runs tests across multiple browsers:- Chromium: Default, all tests run
- WebKit: Safari engine, opt-in with
@webkittag - Firefox: Mozilla engine, opt-in with
@firefoxtag
Browser-Specific Tests
Test Reports and Artifacts
Test results and artifacts are saved to:- Test results:
artifacts/test-results/ - Screenshots: Captured on test failure
- Videos: Recorded on first retry
- Traces: Full browser trace on failure
- Storage state:
artifacts/storage-states/admin.json
Continuous Integration
Tests run automatically on GitHub Actions for:- Every pull request
- Pushes to main branch
- Release workflows
CI Configuration
In CI environment:- Tests run in headless mode
- Retries: 2 attempts for flaky tests
- Reporters: GitHub Actions reporter + flaky test reporter
- Parallel execution disabled (workers: 1)
forbidOnlyenabled to prevent.only()in CI
Security Testing
Security-focused tests validate:- LFI Prevention: Local file inclusion protection
- Path Traversal: Directory traversal attack prevention
- Selector Injection: CSS selector injection prevention
- XSS Protection: Cross-site scripting prevention
test-class-security-lfi.php: PHP LFI teststest-class-security-selector.php: Selector injection testssecurity-lfi-path-traversal.spec.js: E2E security tests
Performance Testing
Test performance is optimized:- Parallel processing: PHPCS runs up to 20 files simultaneously
- Caching: Test results cached for unchanged files
- Selective testing: Only run tests for changed components
- Fast feedback: Linters run before longer test suites
Debugging Tests
PHP Unit Test Debugging
E2E Test Debugging
Using Playwright Trace Viewer
View traces from failed tests:Test Coverage
Key areas covered by tests:- Core Classes: Template system, controls, images, security
- Layouts: Grid, masonry, slider, justified, tiles
- Features: Pagination, filtering, sorting, lightbox
- Gutenberg: Block editor integration, patterns, saved layouts
- Archive Mapping: Portfolio post archives and RSS feeds
- Security: Input sanitization, LFI prevention, XSS protection
- Responsive Design: Mobile and tablet viewport testing
- RTL Support: Right-to-left language support
Best Practices
General Testing Guidelines
- Write tests for all new features
- Update tests when modifying existing features
- Keep tests focused and independent
- Use descriptive test names
- Clean up test data in teardown methods
- Mock external dependencies when possible
- Test edge cases and error conditions
PHP Testing Best Practices
- Extend
WP_UnitTestCasefor WordPress integration - Use
setUp()andtearDown()for test isolation - Test both success and failure scenarios
- Verify security measures (sanitization, escaping, nonces)
- Use fixtures for complex test data
- Test WordPress hooks and filters
E2E Testing Best Practices
- Test complete user workflows
- Use semantic selectors (aria-labels, test IDs)
- Wait for elements properly (don’t use fixed delays)
- Test across different browsers when needed
- Verify visual elements are actually visible
- Test both admin and frontend experiences
- Clean up created content after tests
Troubleshooting
Common Issues
wp-env not starting:.wp-env.json.
PHP tests failing:
playwright.config.js or use test.setTimeout().
Flaky E2E tests:
- Use
waitForSelector()instead of fixed delays - Ensure proper cleanup between tests
- Check for race conditions
- Review flaky test report in CI