Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
23
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@miya0001

VCCW + WP-CLI で WordPress のユニットテスト

ユニットテストの話になるとなんか心理的なハードルがあるようですね。

でも実際にはすごく簡単に始められますし、var_dump() を何回も書いたり消したりすることを考えると確実に楽になります。

今回の記事では、VCCW を使った WordPress プラグインのユニットテストについて説明します。

VCCW を使うとてっとりばやく始めることができるのでおすすめです。

ユニットテストで楽になること

ユニットテストは細かい確認作業を自動化してくれます。確認作業を自動化するんですから楽になるに決まってるじゃないですか。

たとえば以下のコード。

function hoge( $n ) {
    if ( ! is_numeric( $n ) ) {
        return new WP_Error( "おいこら数字を入れろや!" );
    }
    return $n + 1;
}

こんな関数を作った場合、何種類かの値をパラメータで渡して戻り値を var_dump() で確認したりしますよね。

そんな時は以下のような感じでオッケー。

/**
 * @test
 */
public function hoge_test() {
    // `hoge( 1 )` の戻り値が2であることを期待
    $this->assertSame( 2, hoge( 1 ) );

    // 文字列が引数の時は WP_Error オブジェクトであることを期待
    $this->assertTrue( is_wp_error( hoge( "hello" ) ) );
}

これをめんどくさいと思うかもしれませんが、このテストコードは別に消す必要ありません。

むしろずっと残しておくべきです。

こうやって細かい確認作業を残しておくことで、開発中に phpunit と叩くだけで、つもりつもったテストがまとめて実行されるわけです。

関数の仕様が変わったらそれにあわせてテストコードを修正したり追加したりすればいいわけです。

バグがあったときにもそのバグを再現したテストを追記していきましょう。

どう考えても便利だと思いません?

あとなにがめんどくさいかって var_dump() で確認する時っていちいちブラウザでみるわけですよね。

phpunit って叩くだけと比べると、それは泣きたくなるほどめんどくさいです。

既存のプラグインにユニットテストを追加

VCCW を使えばユニットテスト環境を構築するのは簡単です。

まず、ゲストマシンに入ってください。

$ vagrant ssh

次にプラグインがあるディレクトリまで移動。ここから先のコマンドはゲストマシンの中でやることに注意。

$ cd /var/www/html/wp-content/plugins/hoge

そこで以下のコマンドを実行してください。

$ wp scaffold plugin-tests hoge

最後の hoge はプラグインのディレクトリ名。WordPress ではこれを slug とも呼びます。

公式ディレクトリにプラグインを登録する際にプラグイン名は後からでも変更できますが、この slug は変更できないので注意しましょう。

以上で、テスト用のファイルもろもろができました。

あとはテストを実際に実行するために必要な WordPress が必要です。

このテスト用の WordPress は他のプラグインが入ってたりデータベースにゴミデータが入っていないまっさらな状態であるべきで、そういう環境を以下のコマンド一発で用意できます。

$ install-wp-tests

このコマンドはテスト用のファイルが生成されたプラグインのディレクトリの直下じゃないとエラーが出るので注意。

あとセットアップされた WordPress はゲストマシンの再起動のたびに消えて無くなります。これはバグとかではなくて、常に綺麗である必要があるからです。

以上で準備はできました。

ユニットテストを実行してみましょう。

$ phpunit

まだテストは一切書いてないですが、たったのこれだけでもこのプラグインは WordPress で有効化された状態でテストが実行されますので、構文エラーは検出できます。

テストコード付きの WordPress プラグインをいちから作成

本来であればテストはプラグインを作りながら同時進行で書いていくべきです。

そうすることで、テストしやすい構造のプラグインができて、より信頼性が高いものになっていくわけです。

作業効率もいいです。ブラウザでの確認作業が激減しますからね。

WP-CLI をつかえばこれも簡単です。

先ほどと同じように VCCW にログイン。

$ vagrant ssh

その後でテスト用のファイル付きのプラグインを以下のコマンドで作成します。

$ wp scaffold plugin foo

これだけで、プラグインの雛形が以下のディレクトリにできているはずです。

$ cd /var/www/html/wp-content/plugins/foo

先ほどと同じようにテスト用のまっさらな WordPress を用意。

$ install-wp-tests

最後にユニットテストを実行。

$ phpunit

テストを書く

テストは、test-sample.php というファイルがありますので、そこに追記していくとこから始めるといいですね。

テストファイルは、このサンプルのように test-*.php みたいなファイル名であれば、全部がまとめて実行されます。

大きなプラグインなら、工夫して複数のファイルに分けておくといいです。

サンプルには以下のようなテストが書かれています。

class SampleTest extends WP_UnitTestCase {

    /**
     * A single example test.
     */
    function test_sample() {
            // Replace this with some actual testing code.
            $this->assertTrue( true );
    }
}

このテストは truetrue であることって意味です。あたりまえですね。笑

ためしに true の部分を false に書き換えるとテストがコケます。ぜひ試してみましょう。

$ phpunit 

F                                                                   1 / 1 (100%)

Time: 2.21 seconds, Memory: 26.00MB

There was 1 failure:

1) SampleTest::test_sample
Failed asserting that false is true.

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

$this->assertTrue() というのはアサーションと言います。この場合、このメソッドの引数に渡された値が true であれば合格。そうでなければ不合格となります。

他にもよく使うのは $this->assertSame() というのがあります。これは第1引数と第二引数が同じであれば合格です。

class SampleTest extends WP_UnitTestCase {

    /**
     * A single example test.
     */
    function test_sample() {
            // Replace this with some actual testing code.
            $this->assertTrue( true );
    }

    /**
     * @test
     */
    function test_option() {
        update_option( "foo", "hello" );
        $this->assertSame( "hello", get_option( "foo" ) );
    }
}

上の例ではもともとあるテストの下に二つ目のテストを追加しました。

テストの内容は、update_option() であらかじめオプションを追加しておいて、同じ値を get_option() で取得できているかを $this->assertSame() でチェックしています。

テストコードの中では WordPress の関数がそのまんま動作するということがミソです。

テスト用のメソッドを追加するときには、メソッド名が test_ ではじまっているか、その上のコメントで @test というアノテーションがセットされていればオッケーです。

アサーションやアノテーションについてはいろいろありますので、PHPUnit のマニュアルをみながら徐々に覚えていくといいと思います。

WP_UnitTestCase について

テスト用のファイルをよく見ると、WP_UnitTestCase のサブクラスであることがわかります。

WP_UnitTestCase というのは、WordPress 本体のユニットテスト用に開発されているクラスで、WordPress に特化した便利なメソッドがいろいろとあります。

たとえば、ダミーの記事を10件ほど放り込みたい場合は以下のような感じの記述をテストに追加します。

$this->factory->post->create_many( 10 );

ほかにもダミーのユーザーや画像をつっこんだりとかもできるんですが、残念ながらこのクラスに関するドキュメントは存在していません。。。

以下の URL のあたりをのぞいてみてください。

あと、Qiita にタグをつけて書いているんですが僕しかいません。。。w

さみしいのでみんなで書こうぜー。

具体的なテストのサンプルを見たいときは以下のURLのあたりをみるといいです。

WordPress 本体のユニットテスト

ユニットテストが書かれているプラグイン

最近では海外の有名プラグインのほとんどでユニットテストが書かれているので、よく使うプラグインのテストを参考にするとわかりやすいかもですね。

いろいろなテストを追加しながら小一時間あそんでみるともうこれなしでは生きていけないはずです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
23
Help us understand the problem. What are the problem?