WordPressのプラグインの自動テストをPHPUnitで on Docker

Dockerを使ってWordPressのプラグイン開発環境を作った際のユニットテストの準備とやり方。
ユニットテストのひな形と実行にWP-CLIのScaffoldingで生成したものを用いる。

1. Dockerの準備

以下の通りファイルを準備してコンテナを立ち上げる。

  • Dockerfile
  • docker-compose.yml
  • .env

Dockerfile

WordPress公式のイメージにPHPUnitとWP-CLIを追加したもの。

FROM wordpress:php5.6

RUN apt-get update && apt-get install -y less wget subversion mysql-client

RUN wget https://phar.phpunit.de/phpunit-5.7.20.phar && \
    chmod +x phpunit-5.7.20.phar && \
    mv phpunit-5.7.20.phar /usr/local/bin/phpunit

RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar && \
    chmod +x wp-cli.phar && \
    mv wp-cli.phar /usr/local/bin/wp

補足説明

タグをphp5.6にしているのはlatestがphp5.6を指していりから。
latestが不意に7.1に変わっても環境が壊れないようにこうしている。

実際PHP5.6のサポート終了は2018年末に迫っているので、いつの間にかlatestが7.1に変わってもおかしくない。
(2017-12追記 12月現在では7.2がlatestになっていた)

そしてPHPUnitのバージョンをphpunit-5.7.20と指定しているのはPHP5.6を使っているため。
PHPUnitの最新版はPHP5.6では動かないので。

補足説明2

公式のイメージのwp-cliのタグがついたものを使わず、php5.6のイメージにWP-CLIを混ぜ込んでいるのは横着かもしれないが理由がある。

wordpress:wp-cliでビルドされるイメージは/var/www/html以下にWordPressがないと動かないのだが、wordpress:php5.6とは違って、コンテナ構築時に/var/www/html以下にWordPressのファイル一式を展開してくれない。
したがってwp-cliはそのままでは動かない。

/var/www/htmlをボリュームとして共有する形にすればこの問題はクリアされる。ただまあそのあたりは本題ではないので今回は横着。

docker-compose.yml

version: "2"
services:
    wordpress:
        build:
            context: .
            dockerfile: Dockerfile
        ports:
            - "8888:80"
        depends_on:
            - db
        environment:
            WORDPRESS_DB_HOST: "db:3306"
        env_file: .env
        volumes:
          - .:/var/www/html/wp-content/plugins/my-plugin
          - for-testing:/tmp
    db: 
        image: mysql:latest
        env_file: .env
        volumes:
            - db-data:/var/lib/mysql

volumes:
    db-data:
        driver: local
    for-testing:
        driver: local

補足説明

/tmpをfor-testingと言うボリュームで保持しているのは、プラグインのユニットテストに必要なファイル一式が後述のテスト環境の準備の際に/tmp以下に展開されるため。
このようにしないと、コンテナを止めた時にそのファイル一式が消えてしまうため、立ち上げ直すたびにテスト環境の準備をやり直さないといけなくなる。

.env

設定ファイル。開発環境なので適当。

WORDPRESS_DB_NAME=wordpress
WORDPRESS_DB_USER=wp_user
WORDPRESS_DB_PASSWORD=hogehoge

MYSQL_ROOT_PASSWORD=devpass
MYSQL_DATABASE=wordpress
MYSQL_USER=wp_user
MYSQL_PASSWORD=hogehoge

ここまで準備が出来たら

$ docker-compose up -d

2. WordPressのインストール

 $ docker-compose exec wordpress wp core install --allow-root --url=http://localhost:8888/ --title=testing --admin_user=wpadmin --admin_email=wpadmin@example.com

WP-CLIを利用しているが、ブラウザでWordPressにアクセスして手動でインストールしてもOK。

3. テストのひな形の作成

WP-CLIを使ってプラグインのテストのひな形を生成。ここでのプラグイン名はmy-plugin。

$ docker-compose exec wordpress wp scaffold plugin-tests my-plugin --allow-root

4. プラグインファイルの作成

とりあえずテストを実行するために空のプラグインファイルを作る。空でもこれがないとテスト実行時にエラーになってしまう。

$ echo "<?php" > my-plugin.php

サンプルのテストがパスしたらこのファイルに実装を書いていく。

5. テスト環境の準備

ユニットテストの実行に必要なファイルがコンテナ内の/tmp以下に展開され、テスト用DBが作成される。
MySQLのrootパスワードは.envファイルで設定したMYSQL_ROOT_PASSWORDを指定する。

$ docker-compose exec wordpress bash -c "/var/www/html/wp-content/plugins/my-plugin/bin/install-wp-tests.sh wordpress_test root 'devpass' db latest"

6. PHPUnitの実行

テストを実行する

$ docker-compose exec wordpress bash -c "cd /var/www/html/wp-content/plugins/my-plugin; phpunit"

無事にサンプルのテストコードがパスしたら、あとは粛々とテストと実装を書いていくのみ。

GitHubにこの手順を最後まで実行したファイル一式を置いておくので、作成する/作成されるファイルを見たい場合は参考に。