Back to Blog
Lesson 28 of the Advanced WordPress Plugin Engineering: Scale, Security & React UIs course
WordPressJune 28, 20263 min read

Integration Testing for WordPress: Database and API Workflows

Master Integration Testing in WordPress. Learn to automate database migration validation and REST API endpoint verification using the official test suite.

WordPressIntegration TestingAutomationPHPUnitREST APIDatabasephpplugin-development

Previously in this course, we explored Unit Testing with PHPUnit: A Guide for WordPress Engineers, where we focused on isolating business logic and mocking dependencies. While unit tests ensure your methods perform correctly in a vacuum, they cannot guarantee that your plugin actually plays nice with the WordPress database or the REST API.

Integration Testing bridges this gap. It verifies that your plugin's components—your repositories, custom tables, and API controllers—function correctly when interacting with the real WordPress core, the filesystem, and the MySQL database.

The WordPress Testing Environment

Unlike standard PHPUnit tests, WordPress integration tests require a specialized environment. When you run your test suite, WordPress boots up a temporary, "disposable" database. This is critical: it allows you to run destructive operations (like truncating tables or running full schema migrations) without touching your development or production data.

To get started, ensure you have the wp-browser or the wp-cli/wp-cli-tests scaffolded. Your tests should extend WP_UnitTestCase rather than the standard PHPUnit\Framework\TestCase.

Testing Database Migrations

In our Knowledge Base plugin, we manage custom tables for article versions. A common pitfall is assuming dbDelta works perfectly across all environments. We must write a test to ensure our migration logic creates the expected schema.

PHP
class MigrationIntegrationTest extends WP_UnitTestCase {
    public function test_knowledge_base_table_creation() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'kb_articles';

        #6A9955">// Trigger the migration logic
        $migration = new KnowledgeBase_Migration();
        $migration->run();

        #6A9955">// Assert the table exists
        $this->assertEquals($table_name, $wpdb->get_var("SHOW TABLES LIKE '$table_name'"));

        #6A9955">// Verify specific columns exist
        $columns = $wpdb->get_col("DESCRIBE $table_name");
        $this->assertContains('article_id', $columns);
        $this->assertContains('version_content', $columns);
    }
}

By hitting the database directly, we confirm that our SQL syntax is compatible with the version of MySQL running in our CI/CD pipeline, catching collation or type errors before they reach production.

Integration Testing for REST API Endpoints

We previously covered Custom REST API Integration: Fetching Data in React, but verifying those endpoints from the server side is equally important. We use WP_REST_Request to simulate incoming traffic.

This allows us to test the entire lifecycle: authentication checks, parameter sanitization, and the final JSON output.

PHP
class ArticleEndpointTest extends WP_UnitTestCase {
    protected $server;

    public function setUp(): void {
        parent::setUp();
        $this->server = rest_get_server();
    }

    public function test_get_article_returns_correct_data() {
        #6A9955">// Setup: Create a post via helper
        $post_id = $this->factory->post->create(['post_type' => 'kb_article']);

        #6A9955">// Create the request
        $request = new WP_REST_Request('GET', '/kb/v1/articles/' . $post_id);
        
        #6A9955">// Dispatch the request
        $response = $this->server->dispatch($request);
        
        #6A9955">// Assertions
        $this->assertEquals(200, $response->get_status());
        $data = $response->get_data();
        $this->assertEquals($post_id, $data['id']);
    }
}

Hands-on Exercise

  1. Setup: If you haven't already, run wp scaffold plugin-tests <plugin-slug> to generate the tests/ directory structure.
  2. Schema Test: Create a new test file tests/test-schema.php. Write a test that verifies your plugin’s main custom table exists after the activate() method is triggered.
  3. API Test: Create tests/test-api.php. Write a test that attempts to access a protected REST API endpoint without a valid nonce or permission, and assert that it returns a 401 Unauthorized or 403 Forbidden status code.

Common Pitfalls

  • Leaking Data: Always use WP_UnitTestCase's built-in cleanup. If you manually insert data, ensure you use wp_delete_post() or similar hooks in tearDown() to prevent side effects in subsequent tests.
  • Ignoring Permissions: Don't just test the "happy path." Integration tests are the perfect place to verify that your permission_callback actually prevents unauthorized users from accessing sensitive data.
  • Slow Tests: Integration tests are inherently slower than unit tests because they involve disk I/O and database operations. Keep them focused on "contract" verification—ensure the API returns the right structure, not every single edge case of your business logic.

Recap

Integration testing provides the safety net required for scaling complex plugins. By leveraging WP_UnitTestCase, we ensure that our database migrations hold up under pressure and our REST API endpoints correctly handle authentication and data serialization. This validates the "integration points" where your code meets the WordPress core.

Up next: We will move into a full Test-Driven Development (TDD) workflow, where we write failing tests before we even touch the feature code.

Similar Posts