PHP code example of alvarodelera / pest-wp-plugin

1. Go to this page and download the library: Download alvarodelera/pest-wp-plugin library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

alvarodelera / pest-wp-plugin example snippets



// tests/Integration/MyPluginTest.php

use function PestWP\createPost;
use function PestWP\createUser;

it('can create posts', function () {
    $post = createPost(['post_title' => 'Hello World']);
    
    expect($post)->toBeInstanceOf(WP_Post::class)
        ->and($post->post_title)->toBe('Hello World');
});

it('can test user permissions', function () {
    $editor = createUser('editor');
    loginAs($editor);
    
    expect(current_user_can('edit_posts'))->toBeTrue()
        ->and(current_user_can('manage_options'))->toBeFalse();
});


// tests/Pest.php

use PestWP\Concerns\InteractsWithDatabase;

// Enable database isolation for integration tests
uses(InteractsWithDatabase::class)->in('Integration');


// tests/Pest.php

use PestWP\Config;
use PestWP\Database\TransactionManager;

/*
|--------------------------------------------------------------------------
| Load Your Plugin
|--------------------------------------------------------------------------
|
| Tell PestWP to load your plugin when WordPress initializes.
| Use the absolute path to your main plugin file.
|
*/

Config::plugins([
    dirname(__DIR__) . '/my-plugin.php',
]);

/*
|--------------------------------------------------------------------------
| Database Isolation
|--------------------------------------------------------------------------
*/

uses()
    ->beforeEach(fn () => TransactionManager::beginTransaction())
    ->afterEach(fn () => TransactionManager::rollback())
    ->in('Integration');


// tests/Pest.php

use PestWP\Config;
use PestWP\Database\TransactionManager;

/*
|--------------------------------------------------------------------------
| Plugin Configuration
|--------------------------------------------------------------------------
*/

// Load your main plugin
Config::plugins(dirname(__DIR__) . '/my-awesome-plugin.php');

// Or load multiple plugins if your plugin has dependencies
Config::plugins([
    dirname(__DIR__) . '/vendor/woocommerce/woocommerce.php', // Dependency
    dirname(__DIR__) . '/my-woo-extension.php',                // Your plugin
]);

// Load MU-plugins (loaded before regular plugins)
Config::muPlugins([
    dirname(__DIR__) . '/tests/mu-plugins/test-helpers.php',
]);

// Set active theme (optional)
Config::theme('twentytwentyfour');

/*
|--------------------------------------------------------------------------
| Custom Setup Hooks
|--------------------------------------------------------------------------
*/

// Run code BEFORE WordPress loads (define constants, etc.)
Config::beforeWordPress(function () {
    define('MY_PLUGIN_DEBUG', true);
    define('MY_PLUGIN_TEST_MODE', true);
});

// Run code AFTER WordPress loads (set options, add filters, etc.)
Config::afterWordPress(function () {
    // Set plugin options for testing
    update_option('my_plugin_api_key', 'test-api-key');
    update_option('my_plugin_settings', [
        'feature_x' => true,
        'feature_y' => false,
    ]);
    
    // Add test-specific filters
    add_filter('my_plugin_external_api', fn() => 'mock-response');
});

/*
|--------------------------------------------------------------------------
| Database Isolation
|--------------------------------------------------------------------------
*/

uses()
    ->beforeEach(fn () => TransactionManager::beginTransaction())
    ->afterEach(fn () => TransactionManager::rollback())
    ->in('Integration');


// tests/Integration/MyPluginTest.php

use function PestWP\createPost;
use function PestWP\createUser;

describe('My Plugin', function () {
    
    it('registers custom post type on init', function () {
        // Your plugin should have registered this via init hook
        expect(post_type_exists('my_custom_type'))->toBeTrue();
    });
    
    it('adds custom meta box', function () {
        do_action('add_meta_boxes', 'post');
        
        global $wp_meta_boxes;
        expect($wp_meta_boxes['post']['normal']['default'])
            ->toHaveKey('my_plugin_meta_box');
    });
    
    it('filters the content', function () {
        $post = createPost(['post_content' => 'Original content']);
        $filtered = apply_filters('the_content', $post->post_content);
        
        expect($filtered)->toContain('Modified by my plugin');
    });
    
    it('



use function PestWP\createPost;
use function PestWP\createUser;

it('can create and retrieve a post', function () {
    $post = createPost([
        'post_title' => 'My Test Post',
        'post_content' => 'Test content here',
    ]);
    
    expect($post)
        ->toBeInstanceOf(WP_Post::class)
        ->and($post->post_title)->toBe('My Test Post');
});

it('can create users with different roles', function () {
    $editor = createUser('editor');
    
    expect($editor->roles)->toContain('editor');
});

// tests/Integration/MyPluginTest.php
it('registers custom post type', function () {
    do_action('init');
    expect(post_type_exists('my_cpt'))->toBeTrue();
});

it('filters content correctly', function () {
    $result = apply_filters('the_content', 'Hello');
    expect($result)->toContain('Modified by my plugin');
});

// tests/Browser/AdminTest.php
it('can create post from admin', function () {
    $config = browser();
    
    // Login first
    visit($config['base_url'] . loginUrl())
        ->type('user_login', $config['admin_user'])
        ->type('user_pass', $config['admin_password'])
        ->press('Log In')
        ->assertPathBeginsWith('/wp-admin');
    
    // Create post
    visit($config['base_url'] . newPostUrl())
        ->type(postTitleSelector(), 'My Post')
        ->click(publishButtonSelector())
        ->wait(1)
        ->click(publishButtonSelector())
        ->assertSee('Post published');
});

use function PestWP\createPost;

// With default values
$post = createPost();

// With custom values
$post = createPost([
    'post_title' => 'Custom Title',
    'post_content' => 'Custom content',
    'post_status' => 'draft',
    'post_type' => 'page',
]);

// IDE autocomplete works!
expect($post->ID)->toBeInt();
expect($post->post_title)->toBe('Custom Title');

use function PestWP\createUser;

// Quick role creation
$editor = createUser('editor');

// With additional arguments
$admin = createUser('administrator', [
    'display_name' => 'Test Admin',
]);

// Full custom arguments
$user = createUser([
    'user_login' => 'testuser',
    'user_email' => '[email protected]',
    'role' => 'author',
]);

use function PestWP\createTerm;

// Create a category
$categoryId = createTerm('Technology');

// Create in custom taxonomy
register_taxonomy('project_type', 'project');
$termId = createTerm('Web Development', 'project_type');

// With additional arguments
$termId = createTerm('Featured', 'category', [
    'description' => 'Featured content',
    'slug' => 'featured',
]);

use function PestWP\createAttachment;

// Auto-generates a dummy image
$attachmentId = createAttachment();

// With parent post
$post = createPost();
$attachmentId = createAttachment('', $post->ID);

// With custom arguments
$attachmentId = createAttachment('', 0, [
    'post_title' => 'My Image',
    'post_excerpt' => 'Image caption',
]);

use function PestWP\loginAs;
use function PestWP\createUser;

it('can test editor permissions', function () {
    $editor = createUser('editor');
    loginAs($editor);
    
    expect(current_user_can('edit_posts'))->toBeTrue()
        ->and(current_user_can('manage_options'))->toBeFalse();
});

// Can also login by user ID
loginAs($userId);

use function PestWP\logout;

it('can logout current user', function () {
    $user = createUser();
    loginAs($user);
    
    expect(isUserLoggedIn())->toBeTrue();
    
    logout();
    
    expect(isUserLoggedIn())->toBeFalse();
});

use function PestWP\currentUser;
use function PestWP\isUserLoggedIn;

it('can get current user', function () {
    $admin = createUser('administrator');
    loginAs($admin);
    
    $current = currentUser();
    expect($current->ID)->toBe($admin->ID)
        ->and($current->roles)->toContain('administrator');
});

it('can check if user is logged in', function () {
    expect(isUserLoggedIn())->toBeFalse();
    
    loginAs(createUser());
    
    expect(isUserLoggedIn())->toBeTrue();
});

use function PestWP\loginAs;
use function PestWP\createUser;

it('can test subscriber permissions', function () {
    loginAs(createUser('subscriber'));
    
    expect(current_user_can('read'))->toBeTrue()
        ->and(current_user_can('edit_posts'))->toBeFalse();
});

it('can test administrator permissions', function () {
    loginAs(createUser('administrator'));
    
    expect(current_user_can('manage_options'))->toBeTrue()
        ->and(current_user_can('delete_users'))->toBeTrue();
});

it('can switch between users', function () {
    $editor = createUser('editor');
    $author = createUser('author');
    
    loginAs($editor);
    expect(current_user_can('edit_others_posts'))->toBeTrue();
    
    loginAs($author);
    expect(current_user_can('edit_others_posts'))->toBeFalse();
});

use function PestWP\createPost;

it('can check post statuses', function () {
    $published = createPost(['post_status' => 'publish']);
    $draft = createPost(['post_status' => 'draft']);
    
    expect($published)->toBePublished();
    expect($draft)->toBeDraft();
});

it('can test WP_Error objects', function () {
    $error = new WP_Error('invalid_data', 'Invalid input');
    
    expect($error)
        ->toBeWPError()
        ->toHaveErrorCode('invalid_data');
});

use function PestWP\createPost;
use function PestWP\createUser;

it('can check post metadata', function () {
    $post = createPost();
    update_post_meta($post->ID, 'price', 99);
    
    expect($post)
        ->toHaveMeta('price', 99)
        ->toHaveMetaKey('price');
});

it('can check user metadata', function () {
    $user = createUser();
    update_user_meta($user->ID, 'favorite_color', 'blue');
    
    expect($user)
        ->toHaveUserMeta('favorite_color', 'blue')
        ->toHaveMetaKey('favorite_color');
});

it('can verify hooks are registered', function () {
    $callback = function() { echo 'test'; };
    
    add_action('init', $callback, 10);
    add_filter('the_content', $callback, 15);
    
    expect('init')->toHaveAction($callback, 10);
    expect('the_content')->toHaveFilter($callback, 15);
});

it('can check post terms', function () {
    $post = createPost();
    $termId = wp_insert_term('Technology', 'category');
    wp_set_post_terms($post->ID, [$termId['term_id']], 'category');
    
    expect($post)->toHaveTerm('Technology', 'category');
});

it('can chain multiple expectations', function () {
    $post = createPost(['post_status' => 'publish']);
    update_post_meta($post->ID, 'featured', true);
    
    expect($post)
        ->toBePublished()
        ->toHaveMeta('featured', true)
        ->and($post->post_title)->toBeString()
        ->and($post->ID)->toBeInt();
});

it('test A creates a post', function () {
    $post = createPost(['post_title' => 'Test Post']);
    expect(get_post($post->ID))->not->toBeNull();
});

it('test B does not see the post from test A', function () {
    // The post from test A doesn't exist here
    $posts = get_posts(['post_title' => 'Test Post']);
    expect($posts)->toBeEmpty();
});


// tests/Browser/PostsTest.php

use function PestWP\Functions\getBrowserConfig;

it('can log into WordPress dashboard', function () {
    $config = getBrowserConfig();

    visit($config['base_url'] . '/wp-login.php')
        ->type('user_login', $config['admin_user'])
        ->type('user_pass', $config['admin_password'])
        ->press('Log In')
        ->assertPathBeginsWith('/wp-admin')
        ->assertSee('Dashboard');
});

it('can create a new post', function () {
    $config = getBrowserConfig();

    visit($config['base_url'] . '/wp-admin/post-new.php')
        ->type('[aria-label="Add title"]', 'My New Post')
        ->press('Publish')
        ->wait(1)
        ->press('Publish') // Confirm
        ->assertSee('Post published');
});

// In tests/Pest.php (created by pest-setup-browser)
function browser(): array
{
    return [
        'base_url' => 'http://localhost:8080',
        'admin_user' => 'admin',
        'admin_password' => 'password',
    ];
}

// tests/Pest.php
function browser(): array
{
    return [
        'base_url' => getenv('WP_URL') ?: 'http://wordpress.test',
        'admin_user' => getenv('WP_ADMIN_USER') ?: 'admin',
        'admin_password' => getenv('WP_ADMIN_PASSWORD') ?: 'password',
    ];
}

use function PestWP\Functions\adminUrl;
use function PestWP\Functions\loginUrl;
use function PestWP\Functions\newPostUrl;
use function PestWP\Functions\editPostUrl;
use function PestWP\Functions\postsListUrl;

// Build admin URLs
loginUrl();                    // http://localhost:8080/wp-login.php
adminUrl();                    // http://localhost:8080/wp-admin/
adminUrl('edit.php');          // http://localhost:8080/wp-admin/edit.php
adminUrl('my-plugin');         // http://localhost:8080/wp-admin/admin.php?page=my-plugin

// Post URLs
newPostUrl();                  // New post
newPostUrl('page');            // New page
editPostUrl(123);              // Edit post ID 123
postsListUrl('post', 'draft'); // List drafts

use function PestWP\Functions\postTitleSelector;
use function PestWP\Functions\publishButtonSelector;
use function PestWP\Functions\blockSelector;
use function PestWP\Functions\editorNoticeSelector;

it('can create a post using locators', function () {
    $config = browser();
    
    visit($config['base_url'] . newPostUrl())
        ->wait(1) // Wait for Gutenberg to load
        ->type(postTitleSelector(), 'My Post')
        ->click(publishButtonSelector())
        ->wait(1)
        ->click(publishButtonSelector())
        ->assertSee('Post published');
});

// Target specific blocks
blockSelector('core/paragraph');  // [data-type='core/paragraph']
blockSelector('core/heading');    // [data-type='core/heading']

use function PestWP\Functions\menuSelector;
use function PestWP\Functions\noticeSelector;
use function PestWP\Functions\tableRowSelector;
use function PestWP\Functions\buttonSelector;

// Menu navigation
menuSelector('Posts');           // Admin menu item
submenuSelector('Settings', 'General'); // Submenu item

// Notices
noticeSelector('success');       // Success notices
noticeSelector('error');         // Error notices

// Data tables
tableRowSelector('My Post');     // Row by title
rowActionSelector('edit');       // Row action link



use PestWP\Concerns\InteractsWithDatabase;

// Enable database isolation for integration tests
uses(InteractsWithDatabase::class)->in('Integration');

// Ensure you have the trait in tests/Pest.php
uses(PestWP\Concerns\InteractsWithDatabase::class)->in('Integration');
bash
export WP_BASE_URL=http://localhost:8080
export WP_ADMIN_USER=admin
export WP_ADMIN_PASSWORD=password