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( '[email protected]', '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( '[email protected]', '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の処理にフックかけて何かしたい時などは、この辺りの要領でユニットテスト書いておくといいかなと思います。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark