PluginWordPress

WooCommerceに依存したプラグインのユニットテストを書く

WooCommerceの機能を利用するプラグインのユニットテストを書きたくなったので、その時の覚書。 WP-CLIでセットアップ wp scaffold pluginでユニットテスト用の諸々も作られるので、そのままセット […]

広告ここから
広告ここまで

WooCommerceの機能を利用するプラグインのユニットテストを書きたくなったので、その時の覚書。

WP-CLIでセットアップ

wp scaffold pluginでユニットテスト用の諸々も作られるので、そのままセットアップします。

$ cd /PATH/TO/WORDPRESS
$ wp scaffold plugin woo-intergation
$ cd woo-intergation

VCCWを使っていれば、このあとinstall-wp-testsを実行するだけでユニットテストの準備が完了します。

$ install-wp-tests

phpunitを実行してこうなったらOK。

$ phpunit
+ phpunit
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.
PHPUnit 5.6.0 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 1.33 seconds, Memory: 26.00MB

OK (1 test, 1 assertion)

ユニットテストの準備

このままだと、コア周りの処理以外は特に実行されていません。
WooCommerceのフックやカスタム属性に対してテストをかけたい時は、WooCommerceプラグインをロードさせてやる必要があります。

そしてQiitaに「WordPressプラグインのユニットテストにおける依存関係の問題を解決する」というちょうど良い記事があります。
ほぼそのまま使えるので、そこの内容に倣って準備していきましょう。

WooCommerceのダウンロード

ユニットテスト用のWordPressにWooCommerceをダウンロードしてきます。
TravisCIで実行する場合はこんな感じでいきましょう。

$ cd bin
$ wget https://raw.githubusercontent.com/horike37/wp-plugin-unittest-dependency-patten/master/bin/install-dependencies.php 
$ php install-dependencies.php 

WooCommerceプラグインをロードする

tests/bootstrap.phpでWooCommerceを読み込んでやればOKなので、そのように設定していきます。

tests/dependencies-array.phpを作る

ここに依存関係にあるプラグインを指定してやります。

<?php
return array(
    'woocommerce' => array(
        'include' => 'woocommerce/woocommerce.php',
        'repo' => 'https://downloads.wordpress.org/plugin/woocommerce.zip',
    )
);

tests/bootstrap.phpで依存プラグインを読み込む

あとは以下のようにして先ほど定義したプラグインを読み込むようにしてやりましょう。

function _manually_load_dependencies()
{
    $local_plugin_directory = dirname( dirname( dirname( __FILE__ ) ) );
    $dependencies = require __DIR__ . '/dependencies-array.php';
    foreach ( $dependencies as $k => $dependency ){
        if ( is_dir( $local_plugin_directory .'/' . $k ) ) {
            require $local_plugin_directory .'/' . $dependency['include'];
            echo "Loaded $k\n";
        } elseif ( is_dir( WP_PLUGIN_DIR . '/' . $k ) ) {
            require WP_PLUGIN_DIR .'/' . $dependency['include'];
            echo "Loaded $k\n";
        } else {
            echo "COULD NOT LOAD $k\n";
        }
    }
}
tests_add_filter( 'muplugins_loaded', '_manually_load_dependencies' );

ここまでで準備ができました。

WooCommerceの関数をテストしてみる

ということでテストを書いてみましょう。
サンプルとして、「wc_create_new_customer()で作成したユーザーのがcustomerロールで登録されているか」というものを用意しました。

tests/test-example.php

class ExampleTest extends WP_UnitTestCase {
    function test_example() {
        $customer_id = wc_create_new_customer( 'hoge@example.com', 'John', 'Wma!B1@$pD' );
        $user = get_userdata( $customer_id );
        $this->assertTrue( in_array( 'customer', $user->roles, true ) );
    }
}

テストを実行する

手順に問題がなければ、以下のように成功メッセージが出るはずです。

$ phpunit
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
Loaded woocommerce
Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.
PHPUnit 5.6.0 by Sebastian Bergmann and contributors.

.                                                                1 / 1 (100%)

Time: 2.39 seconds, Memory: 40.00MB

OK (1 tests, 1 assertions)

フックでこかしてみる

ちゃんとWooCommerceの関数がよばれているか確認する意味も兼ねて、フックを使ってテストをFailさせてみます。

先ほどのテストファイルに、以下のコードを追加してみてください。

    function test_example2() {
        add_action( 'user_register', function( $user_id ) {
            $user = new WP_User( $user_id );
            $user->remove_role( 'customer' );
            $user->add_role( 'administrator' );
            wp_update_user( $user );
        }, 10, 1 );
        $customer_id = wc_create_new_customer( 'hoge@example.com', 'John', 'Wma!B1@$pD' );
        $user = get_userdata( $customer_id );
        $this->assertTrue( in_array( 'customer', $user->roles, true ) );
    }

user_registerフックを使ってwc_create_new_customer()で登録しようとしたユーザーのロールをcustomer以外に変更しようとしています。
かなり物騒な処理ですが、このフックがちゃんと発火していればこのテストは失敗するはずです。

Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
Loaded woocommerce
Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.
PHPUnit 5.6.0 by Sebastian Bergmann and contributors.

.F                                                                2 / 2 (100%)

There was 1 failure:

1) ExampleTest::test_example2
Failed asserting that false is true.

/var/www/html/wp-content/plugins/woo-intergation/tests/test-example.php:65

FAILURES!
Tests: 2, Assertions: 2, Failures: 1.

こけました。

$this->assertTrue()がFalseになっている = 作成したユーザーのロールがcustomer以外になっている」なので、ちゃんとフックの発火などもしている様子です。

ということで、WooCommerceの処理にフックかけて何かしたい時などは、この辺りの要領でユニットテスト書いておくといいかなと思います。

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts