Модульное тестирование в WordPress: WP_Mock и PHPUnit

phpunit

WP_Mock: ( https://github.com/10up/wp_mock ) — это библиотека представляющая из себя API, для  модульного тестирования плагинов WordPress c PHPUnit.
WP_Mock
использует платформу макетов PHP Mockery для модульного тестирования плагинов WordPress. WP_Mock является правильной реализацией модульного тестирования плагинов WordPress, и его можно считать best practice.

Структура плагина

Предполагая, что у вас есть следующая структура плагина:

plugin_structure

 

У вас есть папка плагина под названием « wp-mock-test-demo ». В этой основной папке плагина вы найдете основной файл плагина wp-mock-test-demo.phpи include папку, в которой хранятся классы плагина.

Вышеуказанная структура в настоящее время является общей для многих плагинов. Опять же, это всего лишь пример, и он упрощен для данного урока.

Шаги

Теперь у вас есть все необходимые требования. Ниже приведены шаги по интеграции WP_Mockс приведенным выше примером плагина.

  1. Создайте composer.jsonфайл. Ниже приведено содержимое файла composer.jsonвышеуказанного тестового плагина:
    { 
        "name": "codex-m/wp-mock-test-demo", 
        "description": "Базовый плагин для демонстрации интеграции модульного тестирования WP_Mock.", 
        "authors": [ 
            { 
                "name": "Emerson Maningo", 
                "email": " hello@test.com " 
            } 
        ], 
        "require-dev": { 
            "10up/wp_mock": "dev-master", 
            "phpunit/phpunit": "^6.5" 
        }, 
      "autoload": { 
        "classmap": [ 
          "includes/" 
        ] 
      } 
    }

    composer.jsonдолжен находиться в корневом каталоге вашего основного плагина. В приведенном выше примере плагина результирующий путь к композитору.json имеет вид/wp-content/plugins/wp-mock-test-demo/composer.json
    или выполнить в консоле

    composer require --dev 10up/wp_mock

     

  2. Создадим файл конфига  phpunit.xml
    <?xml version="1.0"?>
    <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    bootstrap="./bootstrap.php"
    colors="true"
    convertErrorsToExceptions="true"
    convertNoticesToExceptions="true"
    convertWarningsToExceptions="true"
    beStrictAboutTestsThatDoNotTestAnything="false"
    xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
    >
    <testsuites>
    <testsuite name="your-plugin-tests">
    <directory suffix=".php">./tests/</directory>
    </testsuite>
    </testsuites>
    </phpunit>
  3. Создадим файл автозагрузки
    bootstrap.php в папке test с указанием пути до index.php WP.

    <?php  require_once __DIR__ . '/../../vendor/autoload.php';

    Теперь все готово. Вот как будет выглядеть структура демонстрационного плагина после завершения описанной выше интеграции и установки сторонних библиотек для использования в ваших тестах.

    структура демонстрационного плагина

Написание первого модульного теста

После завершения вышеуказанной установки сторонних зависимостей с помощью композитора. Теперь вы готовы написать свой первый модульный тест с помощью WP_Mock! Давайте используем приведенный выше пример плагина при написании теста. Предположим, что класс плагина class-wp-mock-demo-plugin.phpсодержит следующий код:

<?php 
/**
 * WP Mock Demo Plugin Class
 * @author emerson
 *
 */
class WP_Mock_Demo_Plugin {
    
    /**
     * Init hooks
     */
    public function init_hooks() {
        add_filter( 'document_title_parts',  array( $this, 'append_login_status_to_title' ) , 10, 1 );        
    }
    
    /**
     * Append login status to title
     * @param string $title
     */
    public function append_login_status_to_title( array $title ) {
        if ( is_user_logged_in() ) {
            $title[] = 'USER LOGGED-IN';
         }
        return $title;
    }    
    
}

В зависимости от кода класса существует два метода. Первый метод init_hooksпредназначен для инициализации хуков плагина. Второй метод — обратный вызов фильтра WordPress document_title_parts. Цель состоит в том, чтобы добавить статус входа в заголовок записи или страниц WordPress. Предположим, вы проверите, что эти два метода работают должным образом. Вам нужно будет написать два модульных теста:

  • Метод тестирования init_hooks, чтобы убедиться, что он инициализирует перехватчики
  • Проверьте append_login_status_to_title, добавляется ли текст USER LOGGED-INк тегу заголовка, когда пользователь входит в систему.

Наконец, чтобы написать собственный модульный тест:

  1. Создайте файл PHP с именем test-wp-mock-demo-plugin.phpи сохраните его в папкеunit-tests/tests
  2. Внутри этого тестового файла добавьте этот код по умолчанию:
    <?php
    /**
     * Tests WP_Mock_Demo_Plugin
     * 
     */
    class Test_WP_Mock_Demo_Plugin extends PHPUnit\Framework\TestCase {
    	/**
    	 * Setup WP_Mock for each test
    	 */
    	public function setUp() {
    		\WP_Mock::setUp();
    	}	
    	/**
    	 * Clean up after the test is run
    	 */
    	public function tearDown() {
    	    $this->addToAssertionCount(
    	        \Mockery::getContainer()->mockery_getExpectationCount()
    	        );
    		\WP_Mock::tearDown();
    	}	
    }

    Это WP_Mockфайл шаблона теста по умолчанию. Каждый раз, когда вы добавляете новый тестовый файл, начните с этого шаблона. Он состоит из добавления базовой настройки и разбора WP_Mockтеста.

  3. Теперь пришло время добавить реальные тесты. Ниже приведен полный код тестов:
    <?php
    /**
     * Tests WP_Mock_Demo_Plugin
     * 
     */
    class Test_WP_Mock_Demo_Plugin extends PHPUnit\Framework\TestCase {
    	/**
    	 * Setup WP_Mock for each test
    	 */
    	public function setUp() {
    		\WP_Mock::setUp();
    	}	
    	/**
    	 * Clean up after the test is run
    	 */
    	public function tearDown() {
    	    $this->addToAssertionCount(
    	        \Mockery::getContainer()->mockery_getExpectationCount()
    	        );
    		\WP_Mock::tearDown();
    	}
    	/**
    	 * Instantiate an instance of the class to be tested
    	 * @return WP_Mock_Demo_Plugin
    	 */
    	private function get_subject() {
    	    $test_subject = new WP_Mock_Demo_Plugin();
    	    return $test_subject;
    	}
    	/**
    	 * @test
    	 * Test that hooks are initialized
    	 */
    	public function it_adds_init_hoooks() {
    	    //Get an instance of the subject to be tested
    	    $test_subject = $this->get_subject();
    	    
    	    /**
    	     * Ensure the filter added
    	     * Documentation https://github.com/10up/wp_mock#mocking-actions-and-filters
    	     */
    	    \WP_Mock::expectFilterAdded( 'document_title_parts',  array( $test_subject, 'append_login_status_to_title' ) , 10, 1 );
    	    
    	    //Now test the init hook() method of this class to check if this filter is really added
    	    $test_subject->init_hooks();
    	}
    	/**
    	 * @test
    	 * Test that it appends USER LOGGED-IN to title when user is logged-in
    	 */
    	public function it_appends_user_loggedin_to_title() {
    	    //Get an instance of the subject to be tested
    	    $test_subject = $this->get_subject();
    	    
    	    /**
    	     * Mock 'is_user_logged_in' WordPress core function
    	     * Documentation: https://github.com/10up/wp_mock#mocking-wordpress-core-functions
    	     */
    	    \WP_Mock::userFunction( 'is_user_logged_in', array(
    	        'times' => 1,
    	        'return' => true
    	    ) );
    	    
    	    //Mock original title
    	    $original_title = array();
    	    $original_title[] = 'Original title';
    	    
    	    //Set expected result
    	    $expected_result = $original_title;
    	    $expected_result[] = "USER LOGGED-IN";
    	    
    	    //Now test the append_login_status_to_title() to make sure that filters title and appends USER LOGGED-IN text	    
    	    $filtered_title = $test_subject->append_login_status_to_title( $original_title );
    	    
    	    //Now let's assert that the filtered title is one we expected.
    	    $this->assertSame( $expected_result, $filtered_title );	    
    	    
    	}
    	
    }

Подробности читайте в комментариях к коду в тесте. Объяснение этого выходит за рамки данного руководства. Для получения дополнительной информации обратитесь к следующей документации:

Базовое использование WP_Mock.
Утверждения PHPUnit.

Запуск модульного теста

Чтобы запустить тест, выполните это на терминале:

./vendor/bin/phpunit --configuration phpunit.xml

Результаты теста будут показаны, как показано ниже:

$ ./vendor/bin/phpunit --configuration phpunit.xml
PHPUnit 6.5.5 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 31 ms, Memory: 6.00MB

OK (2 tests, 3 assertions)

Demo

Вы можете получить образец демонстрационного плагина, использованного в этом руководстве, на GitHub: https://github.com/codex-m/wp-mock-test-demo .

Где еще почитать

Где еще почитать на эту тему:

Используем PHPCS в WordPress с WPCS стандартом

WP_Mock PHPUnit Testing Framework to WordPress Plugin: Complete Guide

The practice of WordPress unit testing

Using PHP CodeSniffer For MAMP and WordPress

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *