Pest
Modern és elegáns PHP tesztelési keretrendszer WordPress fejlesztéshez.
This content is not available in your language yet.
A Pest egy modern, elegáns PHP tesztelési keretrendszer, amely a PHPUnit-ra épül. Tiszta, olvasható szintaxist és kiváló fejlesztői élményt biztosít WordPress bővítmények és témák teszteléséhez.
Miért Pest?
Szekció neve “Miért Pest?”- Elegáns szintaxis - Olvasható, kifejező tesztek
- PHPUnit kompatibilis - Meglévő tesztek működnek
- Gyors - Párhuzamos teszt futtatás
- Modern - PHP 8+ funkciók támogatása
- Plugin rendszer - Bővíthető funkcionalitás
- Kiváló DX - Watch mode, coverage, snapshot tesztek
Telepítés
Szekció neve “Telepítés”Composer
Szekció neve “Composer”composer require pestphp/pest --dev --with-all-dependenciesInicializálás
Szekció neve “Inicializálás”./vendor/bin/pest --initEz létrehozza a tests/ mappát és a szükséges konfigurációs fájlokat.
Alapvető szintaxis
Szekció neve “Alapvető szintaxis”Első teszt
Szekció neve “Első teszt”<?phptest('example', function () { expect(true)->toBeTrue();});
test('addition works', function () { expect(1 + 1)->toBe(2);});it() szintaxis
Szekció neve “it() szintaxis”it('can add numbers', function () { $result = 1 + 1; expect($result)->toBe(2);});
it('can concatenate strings', function () { $result = 'Hello' . ' ' . 'World'; expect($result)->toBe('Hello World');});describe() csoportok
Szekció neve “describe() csoportok”describe('Calculator', function () { it('can add', function () { expect(add(1, 2))->toBe(3); });
it('can subtract', function () { expect(subtract(5, 3))->toBe(2); });
it('can multiply', function () { expect(multiply(3, 4))->toBe(12); });});Expectations (elvárások)
Szekció neve “Expectations (elvárások)”Alapvető assertions
Szekció neve “Alapvető assertions”// Egyenlőségexpect($value)->toBe(5); // Strict (===)expect($value)->toEqual(5); // Loose (==)
// Típus ellenőrzésexpect($value)->toBeString();expect($value)->toBeInt();expect($value)->toBeFloat();expect($value)->toBeBool();expect($value)->toBeArray();expect($value)->toBeObject();expect($value)->toBeNull();
// Logikai értékekexpect($value)->toBeTrue();expect($value)->toBeFalse();expect($value)->toBeTruthy();expect($value)->toBeFalsy();
// Ürességexpect($value)->toBeEmpty();expect($value)->not->toBeEmpty();Tömbök
Szekció neve “Tömbök”// Tömb tartalomexpect($array)->toContain('apple');expect($array)->toContainEqual(['name' => 'John']);expect($array)->toHaveKey('name');expect($array)->toHaveKeys(['name', 'email']);expect($array)->toHaveCount(3);
// Tömb struktúraexpect($array)->toMatchArray([ 'name' => 'John',]);Stringek
Szekció neve “Stringek”expect($string)->toContain('hello');expect($string)->toStartWith('Hello');expect($string)->toEndWith('World');expect($string)->toMatch('/^Hello/');expect($string)->toHaveLength(11);Objektumok
Szekció neve “Objektumok”expect($object)->toBeInstanceOf(User::class);expect($object)->toHaveProperty('name');expect($object)->toHaveProperty('name', 'John');expect($object)->toHaveMethod('save');Exceptions
Szekció neve “Exceptions”expect(fn() => throwException()) ->toThrow(Exception::class);
expect(fn() => throwException()) ->toThrow(Exception::class, 'Error message');
expect(fn() => throwException()) ->toThrow(InvalidArgumentException::class);expect($json)->toBeJson();expect($json)->json()->toHaveKey('data');expect($json)->json()->data->toBeArray();WordPress tesztelés
Szekció neve “WordPress tesztelés”WordPress test bootstrap
Szekció neve “WordPress test bootstrap”tests/Pest.php:
<?php
// WordPress test bootstrap betöltéserequire_once dirname(__DIR__) . '/vendor/autoload.php';
// WordPress test librarydefine('WP_TESTS_DIR', '/tmp/wordpress-tests-lib');require_once WP_TESTS_DIR . '/includes/functions.php';
// Plugin aktiválása tesztelésheztests_add_filter('muplugins_loaded', function () { require dirname(__DIR__) . '/my-plugin.php';});
require_once WP_TESTS_DIR . '/includes/bootstrap.php';Plugin funkcionalitás tesztelése
Szekció neve “Plugin funkcionalitás tesztelése”<?phptest('plugin is active', function () { expect(is_plugin_active('my-plugin/my-plugin.php'))->toBeTrue();});
test('shortcode is registered', function () { expect(shortcode_exists('my_shortcode'))->toBeTrue();});
test('custom post type is registered', function () { expect(post_type_exists('book'))->toBeTrue();});Post tesztelése
Szekció neve “Post tesztelése”test('can create post', function () { $post_id = wp_insert_post([ 'post_title' => 'Test Post', 'post_content' => 'Test content', 'post_status' => 'publish', ]);
expect($post_id)->toBeInt(); expect($post_id)->toBeGreaterThan(0);
$post = get_post($post_id); expect($post->post_title)->toBe('Test Post');});
test('can update post meta', function () { $post_id = wp_insert_post([ 'post_title' => 'Test Post', 'post_status' => 'publish', ]);
update_post_meta($post_id, 'custom_field', 'custom_value');
expect(get_post_meta($post_id, 'custom_field', true)) ->toBe('custom_value');});User tesztelése
Szekció neve “User tesztelése”test('can create user', function () {
expect($user_id)->toBeInt(); expect($user_id)->toBeGreaterThan(0);
$user = get_user_by('id', $user_id);});
test('user has correct role', function () { $user = new WP_User($user_id); $user->set_role('editor');
expect($user->has_cap('edit_posts'))->toBeTrue(); expect($user->has_cap('manage_options'))->toBeFalse();});REST API tesztelése
Szekció neve “REST API tesztelése”test('REST endpoint returns posts', function () { // Post létrehozása wp_insert_post([ 'post_title' => 'Test Post', 'post_status' => 'publish', ]);
// REST request $request = new WP_REST_Request('GET', '/wp/v2/posts'); $response = rest_do_request($request);
expect($response->get_status())->toBe(200); expect($response->get_data())->toBeArray(); expect($response->get_data())->not->toBeEmpty();});
test('custom REST endpoint works', function () { $request = new WP_REST_Request('GET', '/my-plugin/v1/data'); $response = rest_do_request($request);
expect($response->get_status())->toBe(200); expect($response->get_data())->toHaveKey('success');});Hooks és Filters tesztelése
Szekció neve “Hooks és Filters tesztelése”test('filter modifies content', function () { // Filter callback hozzáadása a pluginban add_filter('the_content', function ($content) { return $content . '<p>Added by plugin</p>'; });
$result = apply_filters('the_content', 'Original content');
expect($result)->toContain('Added by plugin');});
test('action is triggered', function () { $triggered = false;
add_action('my_plugin_action', function () use (&$triggered) { $triggered = true; });
do_action('my_plugin_action');
expect($triggered)->toBeTrue();});Datasets (adatkészletek)
Szekció neve “Datasets (adatkészletek)”Egyszerű dataset
Szekció neve “Egyszerű dataset”test('validates email', function (string $email, bool $expected) { expect(is_email($email))->toBe($expected);})->with([ ['invalid-email', false], ['', false],]);Nevesített dataset
Szekció neve “Nevesített dataset”dataset('valid emails', []);
dataset('invalid emails', [ 'no at' => ['testexample.com'], 'no domain' => ['test@'], 'empty' => [''],]);
test('accepts valid email', function (string $email) { expect(is_email($email))->toBeTruthy();})->with('valid emails');
test('rejects invalid email', function (string $email) { expect(is_email($email))->toBeFalsy();})->with('invalid emails');Kombinált datasets
Szekció neve “Kombinált datasets”test('multiplication', function (int $a, int $b, int $expected) { expect($a * $b)->toBe($expected);})->with([ [2, 3, 6], [4, 5, 20], [0, 10, 0], [-2, 3, -6],]);Mocking
Szekció neve “Mocking”Mock objektumok
Szekció neve “Mock objektumok”test('service calls repository', function () { $repository = mock(UserRepository::class) ->expect( find: fn($id) => new User(['id' => $id, 'name' => 'John']) );
$service = new UserService($repository); $user = $service->getUser(1);
expect($user->name)->toBe('John');});Függvény mocking
Szekció neve “Függvény mocking”test('function is called', function () { $mock = mock('wp_mail') ->andReturn(true);
$mock->shouldHaveBeenCalled(); expect($result)->toBeTrue();});Partial mock
Szekció neve “Partial mock”test('partial mock', function () { $user = mock(User::class)->makePartial(); $user->shouldReceive('save')->andReturn(true);
$user->name = 'John'; $result = $user->save();
expect($user->name)->toBe('John'); expect($result)->toBeTrue();});Fixtures és Factories
Szekció neve “Fixtures és Factories”beforeEach / afterEach
Szekció neve “beforeEach / afterEach”beforeEach(function () {});
afterEach(function () { wp_delete_user($this->user);});
test('user exists', function () { expect(get_user_by('id', $this->user))->not->toBeFalse();});Factory pattern
Szekció neve “Factory pattern”function createPost(array $attributes = []): int { return wp_insert_post(array_merge([ 'post_title' => 'Test Post', 'post_content' => 'Test content', 'post_status' => 'publish', ], $attributes));}
// Teszttest('post factory creates post', function () { $post_id = createPost(['post_title' => 'Custom Title']);
expect(get_post($post_id)->post_title)->toBe('Custom Title');});Coverage (lefedettség)
Szekció neve “Coverage (lefedettség)”Coverage futtatás
Szekció neve “Coverage futtatás”# HTML report./vendor/bin/pest --coverage --coverage-html coverage
# Text output./vendor/bin/pest --coverage
# Minimum coverage ellenőrzés./vendor/bin/pest --coverage --min=80Coverage konfiguráció
Szekció neve “Coverage konfiguráció”phpunit.xml:
<phpunit> <coverage> <include> <directory suffix=".php">./src</directory> </include> <exclude> <directory>./src/views</directory> </exclude> </coverage></phpunit>Watch mode
Szekció neve “Watch mode”# Fájl változások figyelése./vendor/bin/pest --watch
# Specifikus mappa figyelése./vendor/bin/pest --watch --filter=UnitParallel tesztelés
Szekció neve “Parallel tesztelés”# Párhuzamos futtatás./vendor/bin/pest --parallel
# CPU szálak megadása./vendor/bin/pest --parallel --processes=4Snapshot tesztelés
Szekció neve “Snapshot tesztelés”# Plugin telepítésecomposer require spatie/pest-plugin-snapshots --devtest('json output matches snapshot', function () { $data = get_plugin_settings();
expect($data)->toMatchJsonSnapshot();});
test('html output matches snapshot', function () { $html = render_template('widget');
expect($html)->toMatchSnapshot();});Konfigurációs fájlok
Szekció neve “Konfigurációs fájlok”pest.php
Szekció neve “pest.php”<?phpuses(Tests\TestCase::class)->in('Feature');uses(Tests\Unit\TestCase::class)->in('Unit');
// Globális függvényekfunction createUser(array $attributes = []): WP_User { $user_id = wp_create_user( $attributes['login'] ?? 'testuser' . uniqid(), $attributes['password'] ?? 'password', $attributes['email'] ?? 'test' . uniqid() . '@example.com' ); return new WP_User($user_id);}
// Globális expect kiegészítésekexpect()->extend('toBePublished', function () { return $this->toHaveProperty('post_status', 'publish');});phpunit.xml
Szekció neve “phpunit.xml”<?xml version="1.0" encoding="UTF-8"?><phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" bootstrap="tests/bootstrap.php" colors="true"> <testsuites> <testsuite name="Unit"> <directory>tests/Unit</directory> </testsuite> <testsuite name="Feature"> <directory>tests/Feature</directory> </testsuite> </testsuites> <coverage> <include> <directory suffix=".php">./src</directory> </include> </coverage></phpunit>CI/CD integráció
Szekció neve “CI/CD integráció”GitHub Actions
Szekció neve “GitHub Actions”name: Tests
on: [push, pull_request]
jobs: test: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4
- name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.2' coverage: xdebug
- name: Install dependencies run: composer install
- name: Run tests run: ./vendor/bin/pest --coverage --min=80