Skip to main content

Testing

Complete guide to the GSM Middleware automated test suite, including setup, running tests, writing new tests, and the WordPress stub system.

Overview

GSM Middleware uses PHPUnit for unit testing with a custom WordPress function stub system that allows tests to run without a full WordPress installation.

Test Stack:

Version Added: 1.18.26


Quick Start

Install Dependencies

cd wp-content/plugins/gsm-middleware
composer install

Run All Tests

composer test

Run Unit Tests Only

composer test:unit

Run with Coverage

composer test:coverage

This generates an HTML coverage report in coverage/.


Test Suite Structure

tests/
├── bootstrap.php # Test bootstrap (loads stubs, configures autoloading)
├── GSM_Test_Case.php # Base test class with common assertions
├── stubs/
│ ├── wordpress-functions.php # WordPress function stubs
│ └── class-wp-rest.php # WP REST API class stubs
└── Unit/
├── Plugin_Bootstrap_Test.php
├── Security_Manager_Test.php
├── Cron_Manager_Test.php
├── Migration_Runner_Test.php
├── Schema_Verifier_Test.php
├── Inventory_Sync_Coordinator_Test.php
├── Product_Webhook_Handler_Test.php
├── PayArc_Webhook_API_Test.php
├── External_Orders_API_Test.php
├── Lookups_API_Test.php
└── ... (32 test files total)

PHPUnit Configuration

The phpunit.xml.dist file defines two test suites:

SuiteDirectoryPurpose
Unittests/Unit/WordPress-independent unit tests
Integrationtests/Integration/Tests requiring WordPress (future)

Writing Tests

Base Test Class

All tests should extend GSM_Test_Case, which provides:

use GSM\Middleware\Tests\GSM_Test_Case;

class My_Feature_Test extends GSM_Test_Case
{
public function test_something(): void
{
// Arrange, Act, Assert
}
}

Available Helper Methods:

MethodDescription
assertValidJson($string)Assert a string is valid JSON
assertDateFormat($date, $format)Assert a date matches a format
getProtectedProperty($object, $property)Access protected/private properties via reflection
callProtectedMethod($object, $method, $args)Call protected/private methods via reflection

Namespace Convention

Tests use PSR-4 autoloading under GSM\Middleware\Tests\:

namespace GSM\Middleware\Tests\Unit;

WordPress Function Stubs

The test bootstrap automatically loads WordPress function stubs so tests can call functions like get_option(), sanitize_text_field(), etc. without WordPress being loaded.

Available stubs include:

CategoryFunctions
Optionsget_option, update_option, delete_option, get_transient, set_transient, delete_transient
Sanitizationsanitize_text_field, sanitize_email, wp_kses_post, absint, esc_html, esc_attr, esc_url
Usercurrent_user_can, get_current_user_id, wp_get_current_user
HTTPwp_remote_get, wp_remote_post, wp_remote_retrieve_body, wp_remote_retrieve_response_code
Hooksadd_action, add_filter, do_action, apply_filters, remove_action, remove_filter
REST APIregister_rest_route, rest_ensure_response
Miscwp_json_encode, wp_generate_password, wp_hash, wp_create_nonce, is_wp_error

WP REST API Stubs

For testing REST controllers, stubs are provided for:

  • WP_REST_Request — with get_param(), get_params(), get_header(), get_body(), get_json_params()
  • WP_REST_Response — with set_status(), get_status(), get_data()
  • WP_REST_Controller — base class
  • WP_REST_Server — with method constants (READABLE, CREATABLE, etc.)

Example Test

namespace GSM\Middleware\Tests\Unit;

use GSM\Middleware\Tests\GSM_Test_Case;
use GSM\Middleware\Security\Security_Manager;

class Security_Manager_Test extends GSM_Test_Case
{
private Security_Manager $security_manager;

protected function setUp(): void
{
parent::setUp();
$this->security_manager = new Security_Manager();
}

public function test_encrypt_decrypt_roundtrip(): void
{
$plaintext = 'sensitive-api-key-12345';
$encrypted = $this->security_manager->encrypt($plaintext);

$this->assertNotEquals($plaintext, $encrypted);
$this->assertEquals($plaintext, $this->security_manager->decrypt($encrypted));
}

public function test_encrypt_empty_string(): void
{
$this->assertEmpty($this->security_manager->encrypt(''));
}
}

Composer Scripts

ScriptCommandDescription
testphpunitRun all test suites
test:unitphpunit --testsuite UnitRun unit tests only
test:coveragephpunit --coverage-html coverage/Generate HTML coverage report

Test Coverage Summary

As of v1.18.28, the test suite includes:

  • 355 tests across 32 test files
  • 787 assertions total
  • Coverage across all major subsystems:
    • Core (plugin bootstrap, constants, autoloading)
    • Security (encryption, hashing, token generation)
    • Database (migrations, schema verification)
    • Cron (crontab generation, scheduling)
    • Sync (inventory coordination, product webhooks)
    • REST API (PayArc webhooks, external orders, lookups)