wpstarter/o-testbench-core
Testing helper for WpStarter development, ported from Laravel's Testbench component. Provides a familiar testing harness for WpStarter packages, with version compatibility matching WpStarter 1.x to Testbench Core 1.x. See the original Testbench docs for detailed usage.
Installation Add the package via Composer in your WordPress project:
composer require wpstarter/o-testbench-core
Publish the config (if needed):
php artisan vendor:publish --provider="WpStarter\TestbenchCore\TestbenchCoreServiceProvider"
First Test Case
Create a basic test file in tests/Feature/ (e.g., ExampleTest.php):
<?php
namespace Tests\Feature;
use Tests\TestCase;
use WP_UnitTestCase;
class ExampleTest extends TestCase {
public function test_example() {
$this->assertTrue(true);
}
}
Run Tests Execute tests via Artisan:
php artisan test
Or use WP-CLI:
wp testbench run
Bootstrapping WordPress
Use WP_UnitTestCase for WordPress-specific assertions and environment setup:
public function setUp(): void {
parent::setUp();
$this->factory = $this->make( \WP_UnitTest_Factory::class );
}
Database Testing Leverage the built-in test database:
public function test_post_creation() {
$post_id = $this->factory->post->create();
$this->assertNotFalse($post_id);
}
Hooks and Filters
Test WordPress hooks with add_filter()/add_action():
public function test_custom_filter() {
add_filter('the_title', function($title) {
return 'Modified: ' . $title;
});
$post = $this->factory->post->create(['post_title' => 'Test']);
$this->assertStringContainsString('Modified: Test', get_the_title($post));
}
Service Container Bind WordPress classes to Laravel’s container:
$this->app->bind(\WP_Query::class, function() {
return new \WP_Query();
});
Middleware Testing Test WordPress REST API routes with Laravel’s HTTP client:
public function test_rest_route() {
$response = $this->get('/wp-json/wp/v2/posts');
$response->assertStatus(200);
}
Custom Assertions
Extend WP_UnitTestCase for reusable assertions:
class CustomTestCase extends WP_UnitTestCase {
protected function assertPostExists($post_id) {
$this->assertDatabaseHas('posts', ['ID' => $post_id]);
}
}
Database Rollback
Tests run in a fresh database, but ensure setUp()/tearDown() handle rollbacks:
public function tearDown(): void {
parent::tearDown();
global $wpdb;
$wpdb->query("TRUNCATE TABLE wp_options");
}
WordPress Globals
Avoid relying on global state (e.g., $_SERVER, $_GET). Use WP_Mock or factory methods:
// Bad: $_SERVER['REQUEST_METHOD']
// Good: $this->factory->user->create(['role' => 'administrator']);
Plugin/Themes Activation
Manually activate plugins/themes in setUp():
public function setUp(): void {
parent::setUp();
$this->activatePlugin('my-plugin');
}
WP-CLI Debugging Run tests with verbose output:
wp testbench run --verbose
Xdebug
Configure php.ini for Xdebug and use XDEBUG_TRIGGER in .env.testing:
XDEBUG_TRIGGER=1
Test Isolation
Use WP_UnitTestCase::factory() to avoid shared state between tests.
Custom Factories
Extend WP_UnitTest_Factory for domain-specific models:
$this->factory->custom_model->create(['custom_field' => 'value']);
Testbench Core Hooks
Override TestbenchCoreServiceProvider to modify behavior:
public function register() {
parent::register();
$this->app->singleton(\WP_Query::class, function() {
return new CustomWPQuery();
});
}
Parallel Testing
Use php-parallel-lint or pestphp/pest-parallel for faster test suites.
How can I help you explore Laravel packages today?