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