Testing
Comprehensive testing guide for SpeedMate.
Testing Stack
- PHPUnit: Unit and integration tests
- Playwright: End-to-end browser tests
- WP-CLI: Command-line testing
- Docker: Isolated test environments
Setup
Install Dependencies
bash
cd speedmate/
composer install
npm installConfigure Test Environment
bash
# Copy test config
cp tests/.env.example tests/.env
# Edit with your test database
DB_NAME=speedmate_test
DB_USER=root
DB_PASSWORD=password
DB_HOST=localhostUnit Tests
Run All Unit Tests
bash
vendor/bin/phpunitRun Specific Test
bash
vendor/bin/phpunit tests/unit/Cache/StaticCacheTest.phpExample Unit Test
php
<?php
namespace SpeedMate\Tests\Unit\Cache;
use PHPUnit\Framework\TestCase;
use SpeedMate\Cache\StaticCache;
class StaticCacheTest extends TestCase
{
private StaticCache $cache;
protected function setUp(): void
{
$this->cache = StaticCache::instance();
}
public function test_generate_cache_key()
{
$url = 'https://site.com/page';
$key = $this->cache->generate_key($url);
$this->assertMatchesRegularExpression('/^[a-f0-9]{32}$/', $key);
}
public function test_cache_storage()
{
$url = 'https://site.com/test';
$html = '<html><body>Test</body></html>';
$this->cache->save($url, $html);
$cached = $this->cache->get($url);
$this->assertEquals($html, $cached);
}
public function test_cache_expiration()
{
$url = 'https://site.com/expire';
$html = '<html><body>Expire</body></html>';
$this->cache->save($url, $html, 1); // 1 second TTL
sleep(2);
$cached = $this->cache->get($url);
$this->assertNull($cached);
}
}Integration Tests
WordPress Integration
bash
# Install WordPress test suite
bash bin/install-wp-tests.sh speedmate_test root password localhost latestExample Integration Test
php
<?php
namespace SpeedMate\Tests\Integration;
use WP_UnitTestCase;
use SpeedMate\Cache\StaticCache;
use SpeedMate\Perf\BeastMode;
class BeastModeTest extends WP_UnitTestCase
{
public function test_auto_caching_after_threshold()
{
$url = home_url('/test-post');
// Create post
$post_id = $this->factory->post->create([
'post_title' => 'Test Post',
'post_status' => 'publish',
]);
// Simulate 100 views
for ($i = 0; $i < 100; $i++) {
do_action('speedmate_page_view', $url);
}
// Check if auto-cached
$cache = StaticCache::instance();
$this->assertTrue($cache->is_cached($url));
}
public function test_cache_invalidation_on_post_update()
{
$post_id = $this->factory->post->create();
$url = get_permalink($post_id);
// Cache the post
StaticCache::instance()->save($url, '<html>Test</html>');
// Update post
wp_update_post(['ID' => $post_id, 'post_title' => 'Updated']);
// Cache should be cleared
$this->assertFalse(StaticCache::instance()->is_cached($url));
}
}E2E Tests
Playwright Setup
bash
# Install Playwright
npm install @playwright/test
npx playwright installExample E2E Test
javascript
// tests/e2e/cache.spec.js
const { test, expect } = require('@playwright/test');
test.describe('Cache Functionality', () => {
test('should serve cached page on second visit', async ({ page }) => {
// First visit - cache miss
await page.goto('http://localhost:8080/');
let cacheHeader = await page.evaluate(() => {
return document.querySelector('meta[http-equiv="X-Cache"]')?.content;
});
expect(cacheHeader).toBe('MISS');
// Second visit - cache hit
await page.goto('http://localhost:8080/');
cacheHeader = await page.evaluate(() => {
return document.querySelector('meta[http-equiv="X-Cache"]')?.content;
});
expect(cacheHeader).toBe('HIT');
});
test('should flush cache via admin interface', async ({ page }) => {
// Login
await page.goto('http://localhost:8080/wp-admin');
await page.fill('#user_login', 'admin');
await page.fill('#user_pass', 'password');
await page.click('#wp-submit');
// Navigate to SpeedMate settings
await page.goto('http://localhost:8080/wp-admin/options-general.php?page=speedmate');
// Click flush button
await page.click('button:has-text("Flush Cache")');
// Verify success message
await expect(page.locator('.notice-success')).toContainText('Cache flushed');
});
});Run E2E Tests
bash
npx playwright testPerformance Testing
Lighthouse CI
yaml
# .github/workflows/lighthouse.yml
name: Lighthouse CI
on: [push]
jobs:
lighthouse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- name: Run Lighthouse
run: |
npm install -g @lhci/cli
lhci autorun --collect.url=http://localhost:8080Load Testing
bash
# Install k6
brew install k6
# Run load test
k6 run tests/performance/load-test.jsExample load test:
javascript
// tests/performance/load-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
stages: [
{ duration: '30s', target: 20 }, // Ramp up to 20 users
{ duration: '1m', target: 20 }, // Stay at 20 users
{ duration: '30s', target: 0 }, // Ramp down
],
};
export default function () {
let response = http.get('http://localhost:8080/');
check(response, {
'status is 200': (r) => r.status === 200,
'cache hit': (r) => r.headers['X-Cache'] === 'HIT',
'response time < 50ms': (r) => r.timings.duration < 50,
});
sleep(1);
}WP-CLI Testing
Test Cache Operations
bash
# Flush cache
wp speedmate flush
echo $? # Should be 0 on success
# Warm cache
wp speedmate warm --urls=https://site.com/
echo $? # Should be 0 on success
# Check stats
wp speedmate statsAutomated Test Script
bash
#!/bin/bash
set -e
echo "Testing SpeedMate WP-CLI commands..."
# Test flush
wp speedmate flush
if [ $? -eq 0 ]; then
echo "✓ Flush test passed"
else
echo "✗ Flush test failed"
exit 1
fi
# Test warm
wp speedmate warm --urls=$(wp option get home)
if [ $? -eq 0 ]; then
echo "✓ Warm test passed"
else
echo "✗ Warm test failed"
exit 1
fi
# Test stats
wp speedmate stats --format=json > /dev/null
if [ $? -eq 0 ]; then
echo "✓ Stats test passed"
else
echo "✗ Stats test failed"
exit 1
fi
echo "All tests passed!"Docker Testing
Test Environment
yaml
# docker-compose.test.yml
version: '3.8'
services:
wordpress:
image: wordpress:latest
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: test
WORDPRESS_DB_PASSWORD: test
WORDPRESS_DB_NAME: test
volumes:
- ./:/var/www/html/wp-content/plugins/speedmate
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_RANDOM_ROOT_PASSWORD: '1'Run Tests in Docker
bash
# Start test environment
docker-compose -f docker-compose.test.yml up -d
# Run tests
docker-compose exec wordpress vendor/bin/phpunit
# Cleanup
docker-compose -f docker-compose.test.yml down -vCoverage
Generate Coverage Report
bash
vendor/bin/phpunit --coverage-html coverage/View Coverage
bash
open coverage/index.htmlCI Coverage
yaml
# .github/workflows/coverage.yml
name: Coverage
on: [push]
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with:
php-version: 8.1
coverage: xdebug
- name: Install dependencies
run: composer install
- name: Run tests with coverage
run: vendor/bin/phpunit --coverage-clover coverage.xml
- name: Upload to Codecov
uses: codecov/codecov-action@v3
with:
files: ./coverage.xmlContinuous Integration
GitHub Actions
yaml
# .github/workflows/tests.yml
name: Tests
on: [push, pull_request]
jobs:
phpunit:
runs-on: ubuntu-latest
strategy:
matrix:
php: [7.4, 8.0, 8.1, 8.2]
wordpress: [6.0, 6.1, 6.2, 6.3]
steps:
- uses: actions/checkout@v3
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- name: Install dependencies
run: composer install
- name: Run PHPUnit
run: vendor/bin/phpunit
playwright:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install Playwright
run: npm ci && npx playwright install --with-deps
- name: Run E2E tests
run: npx playwright testManual Testing
Test Checklist
Cache Functionality:
- [ ] Page cached on first visit
- [ ] Cached page served on second visit
- [ ] Cache invalidated on post update
- [ ] Cache excludes logged-in users
- [ ] Cache respects query strings
Beast Mode:
- [ ] Pages auto-cached after threshold
- [ ] Whitelist patterns work correctly
- [ ] Blacklist patterns work correctly
- [ ] Score calculation accurate
- [ ] Dashboard shows correct stats
Media Optimization:
- [ ] WebP images generated
- [ ] Images lazy loaded
- [ ] Fallback to original format
- [ ] Responsive srcset generated
Performance:
- [ ] Lighthouse score > 90
- [ ] LCP < 2.5s
- [ ] FCP < 1.8s
- [ ] TTI < 3.8s
Debugging Tests
Enable Debug Mode
php
define('SPEEDMATE_DEBUG', true);
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);Verbose PHPUnit
bash
vendor/bin/phpunit --verbose --debugPlaywright Debug
bash
PWDEBUG=1 npx playwright test