PHPackages                             doiftrue/unitest-wp-copy - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. doiftrue/unitest-wp-copy

ActiveLibrary[Testing &amp; Quality](/categories/testing)

doiftrue/unitest-wp-copy
========================

Collection of WordPress core functions and classes that can be used in unit tests to simulate WordPress environment.

7.0.2.4(2d ago)62.3k↑64.6%PHP

Since Jul 27Pushed 2d agoCompare

[ Source](https://github.com/doiftrue/unitest-wp-copy)[ Packagist](https://packagist.org/packages/doiftrue/unitest-wp-copy)[ RSS](/packages/doiftrue-unitest-wp-copy/feed)WikiDiscussions main Synced 2d ago

READMEChangelogDependencies (6)Versions (76)Used By (0)

About
=====

[](#about)

Helper library for PHPUnit tests. It provides selected WordPress core functions and classes that can run without full WordPress bootstrap (database or external services).

The goal is to test real WP pure-PHP behavior instead of mocking everything.

Quick Example (Why This Helps)
------------------------------

[](#quick-example-why-this-helps)

Suppose your code builds preview URLs like this:

```
function build_preview_url( string $title ): string {
	return add_query_arg(
		[
			'preview' => '1',
			'slug'    => sanitize_title( $title ),
		],
		'https://example.com/post.php'
	);
}
```

Without this library, you need to mock `sanitize_title()` and `add_query_arg()`, so they do not validate real WordPress behavior.

With this library, the same test can run real implementations in plain PHPUnit:

```
require_once __DIR__ . '/vendor/autoload.php';
\Unitest_WP_Copy\Bootstrap::init();

$this->assertSame(
	'https://example.com/post.php?preview=1&slug=hello-world',
	build_preview_url( 'Hello World!' )
);
```

Available Symbols
-----------------

[](#available-symbols)

For the full list of available classes/functions, see: [`SYMBOLS-INFO.md`](SYMBOLS-INFO.md)

Quick Start
-----------

[](#quick-start)

1. Install a package line that matches your WordPress version line:

```
composer require --dev doiftrue/unitest-wp-copy:6.9.*
```

2. Initialize the runtime in your PHPUnit bootstrap:

```
require_once __DIR__ . '/vendor/autoload.php';
\Unitest_WP_Copy\Bootstrap::init();
```

3. Write unit tests where many WordPress calls do not need mocking.

Supported WordPress Lines
-------------------------

[](#supported-wordpress-lines)

Use the package line that matches your WP version:

WordPress lineComposer constraint7.0`doiftrue/unitest-wp-copy:7.0.*`6.9`doiftrue/unitest-wp-copy:6.9.*`6.8`doiftrue/unitest-wp-copy:6.8.*`6.7`doiftrue/unitest-wp-copy:6.7.*`6.6`doiftrue/unitest-wp-copy:6.6.*`6.5`doiftrue/unitest-wp-copy:6.5.*`Real release tags use 4 numbers, for example `7.0.2.0`:

- `7.0` is the target WordPress version line;
- `2.0` is this repository's release-script version for that line.

In Composer, use:

- `7.0.2.0` - pin one exact release
- `~7.0.2.0` - allow conservative updates starting from this build (usually small runtime fixes)
- `7.0.*` - allow any update in the WP `7.0` line (new copied functions/classes may appear and affect existing tests)

Bootstrap Overrides and Shared State
------------------------------------

[](#bootstrap-overrides-and-shared-state)

Define overrides before `\Unitest_WP_Copy\Bootstrap::init()`.

```
// tests/bootstrap.php
define( 'ABSPATH', '/srv/wp/' );
define( 'WP_CONTENT_DIR', '/srv/wp/wp-content' );
define( 'WP_CONTENT_URL', 'https://tests.example/wp-content' );
define( 'WP_ENVIRONMENT_TYPE', 'development' );
define( 'WP_DEBUG', true );

// Used by get_option()
$GLOBALS['stub_wp_options'] = (object) [
	'home'                => 'https://unitest-wp-copy.loc',
	'siteurl'             => 'https://unitest-wp-copy.loc',
	'gmt_offset'          => 0,
	'timezone_string'     => 'UTC',
	'language'            => 'en-US',
	'blogdescription'     => 'unitest-wp-copy runtime',
	'admin_email'         => 'admin@unitest-wp-copy.loc',
	'stylesheet'          => 'unitest-wp-copy',
	'use_smilies'         => true,
	'use_balanceTags'     => true,
	'WPLANG'              => '',
	'blog_charset'        => 'UTF-8',
	'html_type'           => 'text/html',
	'thumbnail_size_w'    => 150,
	'thumbnail_size_h'    => 150,
	'thumbnail_crop'      => true,
	'medium_size_w'       => 300,
	'medium_size_h'       => 300,
	'medium_large_size_w' => 768,
	'medium_large_size_h' => 0,
	'large_size_w'        => 1024,
	'large_size_h'        => 1024,
];

// Used by get_site_option()
$GLOBALS['stub_wp_site_options'] = (object) [
	'site_name' => 'Test network',
];

require_once __DIR__ . '/vendor/autoload.php';
\Unitest_WP_Copy\Bootstrap::init();
```

### Redefine Runtime Globals

[](#redefine-runtime-globals)

Runtime globals initialized or updated by bootstrap (shared in one PHP process):

```
$GLOBALS['stub_wp_options']
$GLOBALS['stub_wp_site_options']
$GLOBALS['timestart']
$_SERVER['HTTP_HOST']
$blog_id
$wp_plugin_paths
$shortcode_tags
$wp_locale
$wp_post_types
$wp_taxonomies
$wp_filter
$wp_actions
$wp_filters
$wp_current_filter
$allowedposttags
$allowedtags
$allowedentitynames
$allowedxmlentitynames
$wpsmiliestrans
$wp_smiliessearch
```

If a test mutates these globals/options, restore them in `setUp()` / `tearDown()`.

### How `get_option()` Works

[](#how-get_option-works)

`get_option()` uses `$GLOBALS['stub_wp_options']` instead of a database. Configured options have priority over `WP_Mock` handlers so that a broad mock cannot accidentally change options used by nested runtime calls.

The lookup order is:

1. `pre_option_{$option}` and `pre_option` filters;
2. the value in `$GLOBALS['stub_wp_options']` and the `option_{$option}` filter;
3. a `WP_Mock::userFunction( 'get_option', ... )` handler for an option not present in the store;
4. the `default_option_{$option}` filter and the default value.

Override a configured option by changing the store:

```
$GLOBALS['stub_wp_options']->medium_size_w = 640;
```

Use `WP_Mock` to mock option that not exists in `$GLOBALS['stub_wp_options']`:

```
WP_Mock::userFunction( 'get_option', [
	'args'   => [ 'my_plugin_option', false ],
	'return' => 'test-value',
] );
```

IMPORTANT: `WP_Mock` cannot override an option while it exists in `$GLOBALS['stub_wp_options']`.

### Redefine Constants

[](#redefine-constants)

Constants you can predefine before bootstrap:

```
ABSPATH
WPINC
WP_CONTENT_DIR
WP_CONTENT_URL
WP_ENVIRONMENT_TYPE
WP_START_TIMESTAMP
WP_MEMORY_LIMIT
WP_MAX_MEMORY_LIMIT
WP_DEVELOPMENT_MODE
WP_DEBUG
WP_DEBUG_DISPLAY
WP_DEBUG_LOG
WP_CACHE
SCRIPT_DEBUG
MEDIA_TRASH
SHORTINIT
WP_PLUGIN_DIR
WP_PLUGIN_URL
PLUGINDIR
WPMU_PLUGIN_DIR
WPMU_PLUGIN_URL
MUPLUGINDIR
COOKIEHASH
USER_COOKIE
PASS_COOKIE
AUTH_COOKIE
SECURE_AUTH_COOKIE
LOGGED_IN_COOKIE
TEST_COOKIE
COOKIEPATH
SITECOOKIEPATH
ADMIN_COOKIE_PATH
PLUGINS_COOKIE_PATH
COOKIE_DOMAIN
RECOVERY_MODE_COOKIE
FORCE_SSL_ADMIN
AUTOSAVE_INTERVAL
EMPTY_TRASH_DAYS
WP_POST_REVISIONS
WP_CRON_LOCK_TIMEOUT
CUSTOM_TAGS
```

### Redefine functions

[](#redefine-functions)

Copied functions are wrapped with `if ( ! function_exists( '...' ) )`, so you can override specific functions by defining them before bootstrap init.

When to Use It
--------------

[](#when-to-use-it)

Use it when:

- you need real behavior of selected WP functions/classes in plain PHPUnit;
- your tested code mostly depends on WP pure-PHP logic.

Do not use it when:

- you need a full WordPress runtime and bootstrap;
- your test mostly depends on real DB/network/filesystem-heavy WP behavior.

WP\_Mock Integration (Optional)
-------------------------------

[](#wp_mock-integration-optional)

If you need handler-based mocking for supported functions, install WP\_Mock:

```
composer require --dev 10up/wp_mock
```

Then use WP\_Mock per test:

```
class ExampleTest extends \PHPUnit\Framework\TestCase {

	protected function setUp(): void {
		parent::setUp();
		WP_Mock::setUp();
	}

	protected function tearDown(): void {
		WP_Mock::tearDown();
		parent::tearDown();
	}

	public function test__is_multisite_mocked() {
		WP_Mock::userFunction( 'is_multisite' )->andReturn( true );
		$this->assertTrue( is_multisite() );
	}
}
```

For mock-friendly symbols, check: [`SYMBOLS-INFO.md`](SYMBOLS-INFO.md)

See also: [https://github.com/10up/wp\_mock](https://github.com/10up/wp_mock)

Maintainers
-----------

[](#maintainers)

If you maintain this repository, see the docs in [`docs/`](./docs/) (runtime, parser, config, tests, release flow).

###  Health Score

50

—

FairBetter than 95% of packages

Maintenance100

Actively maintained with recent releases

Popularity27

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~5 days

Total

69

Last Release

2d ago

Major Versions

6.9.2.0 → 7.0.2.02026-06-14

6.9.2.1 → 7.0.2.12026-06-20

6.9.2.2 → 7.0.2.22026-06-28

6.9.2.3 → 7.0.2.32026-07-01

6.9.2.4 → 7.0.2.42026-07-01

### Community

Maintainers

![](https://www.gravatar.com/avatar/4a5b59537b7030cbdd84442d082f9ae993922622afae63296809ecc528d672dc?d=identicon)[doiftrue](/maintainers/doiftrue)

---

Top Contributors

[![doiftrue](https://avatars.githubusercontent.com/u/15121552?v=4)](https://github.com/doiftrue "doiftrue (156 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/doiftrue-unitest-wp-copy/health.svg)

```
[![Health](https://phpackages.com/badges/doiftrue-unitest-wp-copy/health.svg)](https://phpackages.com/packages/doiftrue-unitest-wp-copy)
```

###  Alternatives

[dms/phpunit-arraysubset-asserts

This package provides ArraySubset and related asserts once deprecated in PHPUnit 8

14429.2M361](/packages/dms-phpunit-arraysubset-asserts)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
