WordPressプラグインのユニットテストを依存関係がある別のプラグインとセットで実行する


先日、Contact Form 7という超有名 WordPress プラグインにお礼画面をつけるためのアドオン的なプラグインをちょちょっと作りました。

それ自体は100行にも満たないほどの小さなプラグインなのですが、このケースの場合、元のプラグイン、今回のケースでは Contact Form 7 がアップデートされた時にいち早くそれとの互換性をチェックする必要があります。

これを手作業でやるという選択、もしくは問題が起きてから慌てようという選択ももちろんありですが、エンタープライズな用途ではそんなことは許されません。

そこでこういうケースの場合は、ユニットテストを Travis CI で毎日ぶん回して、今はまだ見ぬ将来の WordPress 及び Contact Form 7 との互換性を自動的にチェックします。

## プラグインにユニットテスト用の環境をセットアップ

これは、WP-CLI を使いましょう。

```
$ wp scaffold plugin-tests my-plugin
```

次に、テスト用の環境をセットアップ。これを Travis CI 上でやるためのもろもろは先ほどの WP-CLI で自動的に生成されておりますので、いまからやるのはローカルでテストを実行するためのものです。

```
$ bash bin/install-wp-tests.sh <db-name> <db-user> <db-pass> [db-host] [wp-version]
```

コマンドの引数はみなさんの環境にあわせてくださいね。

次に動作確認を行うためのPHPUnitを実行して見ましょう。

```
$ phpunit
```

エラーが出なければオッケーです。

## 依存関係があるプラグインをダウンロードするためのシェルスクリプトを用意

次に依存関係があるプラグインをダウンロードするためのシェルスクリプトを用意します。

以下のシェルスクリプトを `install-plugin.sh` というファイル名でプラグイン用のフォルダの `bin/` ディレクトリ以下に保存してください。

```
#!/usr/bin/env bash

set -ex

curl -s $WP_PLUGIN -o plugin.zip
unzip plugin.zip -d .plugin
rm -f plugin.zip
```

## プラグインの最新版のダウンロード URL を調べる

プラグインをダウンロードするには、公式ディレクトリ上のプラグインのダウンロードURLを調べるには、公式ディレクトリのプラグインのページを開いて、ダウンロードのURLをそのままコピペしてください。

現時点での Contact Form 7 の最新版の URL は以下のような感じ。

https://downloads.wordpress.org/plugin/contact-form-7.4.9.zip

また、まだ見ぬ将来の最新版のプラグインとの互換性チェックも自動化したいので、そのダウンロード URL も知る必要がありますが、それは WordPress.org が提供する API を使用することで常に最新版のダウンロード URL を取得できます。

```
$ curl "https://api.wordpress.org/plugins/info/1.0/contact-form-7.json" | jq -r .download_link
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 16995    0 16995    0     0  16995      0 --:--:-- --:--:-- --:--:-- 17359
https://downloads.wordpress.org/plugin/contact-form-7.4.9.zip
```

上の API 用の URL の `contact-form-7` の部分はそのプラグインのスラッグというもので、これはプラグインごとに固有のものであり、公式ディレクトリのプラグインペジの URL でも使用されているので、それをコピペすればオッケーです。

https://ja.wordpress.org/plugins/contact-form-7/

## プラグインをダウンロードしてみる

では、先ほど用意したシェルスクリプトを使用してプラグインをダウンロードしてみましょう。

```
$ export WP_PLUGIN=https://downloads.wordpress.org/plugin/contact-form-7.4.9.zip
$ bash bin/install-plugin.sh
```

以上で、`.plugin` というディレクトリに Contact Form 7 がダウンロードされたはず。

また、最新版を自動判別するための URL を使用するには以下のような感じ。

```
$ export WP_PLUGIN=$(curl "https://api.wordpress.org/plugins/info/1.0/contact-form-7.json" | jq -r .download_link)
$ bash bin/install-plugin.sh
```

## PHPUnit でこのプラグインを強制的に有効化する

PHPUnitを実行する際にテスト用の WordPress 環境に強制的に Contact Form 7 を有効化するには、すでに自動的に生成されているファイル `tests/bootstrap.php` に以下のように `require` するだけです。

```
function _manually_load_plugin() {
	require dirname( dirname( __FILE__ ) ) . '/.plugin/contact-form-7/wp-contact-form-7.php';
	require dirname( dirname( __FILE__ ) ) . '/my-plugin.php';
}
```

追加するのは上の2行目のコードだけで、あとはあらかじめ記述されているはずです。

## ユニットテストを実行してみる

ここまでの手順がうまくいっていれば `phpunit` と叩くだけで、プラグインが有効化された状態でテストが走るはずです。

ためしに、たとえば Contact Form 7 の中で定義されている関数をテストの中で実行してみると、その関数が存在していることを確認できると思います。

## .travis.yml に必要な記述を追加

では、Travis CI 上でこの環境が再現されるようにしましょう。

まず、環境変数を定義して以下の条件でテストが自動的に実行されるようにします。

* PHP7 及び PHP7.1 で動作確認を行うこと
* 現時点での WPrdPress の最新版である 4.8、WordPressの最新版、及び Trunk バージョンで動作確認を行うこと
* Contct Form 7 の今の時点での最新版 4.9 と、将来の最新版で動作確認を行うこと

以上、これらを組み合わせて12通りの環境で動作確認を行います。

WordPress の Trunk バージョンというのは WordPress 本体の開発バージョンの最新版という意味で、今日現在であれば `4.9-betax-xxx`、`4.9` がリリースされた直後から `5.0-alpha-xxx` となります。

こうすることで、最新版がリリースされる前に互換性のトラブルを事前にキャッチするわけです。

では、実際の .travis.yml への記述をみてみましょう。

```
php:
- 7.0
- 7.1
env:
  matrix:
   - WP_VERSION=4.8 WP_MULTISITE=0 WP_PLUGIN=https://downloads.wordpress.org/plugin/contact-form-7.4.9.zip
   - WP_VERSION=latest WP_MULTISITE=0 WP_PLUGIN=https://downloads.wordpress.org/plugin/contact-form-7.4.9.zip
   - WP_VERSION=nightly WP_MULTISITE=0 WP_PLUGIN=https://downloads.wordpress.org/plugin/contact-form-7.4.9.zip
   - WP_VERSION=4.8 WP_MULTISITE=0 WP_PLUGIN=$(curl https://api.wordpress.org/plugins/info/1.0/contact-form-7.json | jq -r .download_link)
   - WP_VERSION=latest WP_MULTISITE=0 WP_PLUGIN=$(curl https://api.wordpress.org/plugins/info/1.0/contact-form-7.json | jq -r .download_link)
   - WP_VERSION=nightly WP_MULTISITE=0 WP_PLUGIN=$(curl https://api.wordpress.org/plugins/info/1.0/contact-form-7.json | jq -r .download_link)
```

次に、`before_script`で先ほど用意したプラグインをダウンロードするためのシェルスクリプトを実行します。

```
before_script:
- bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION
- bash bin/install-plugin.sh
```

あとは Travis CI にサインアップするなりこのリポジトリを有効化するなりして、`git push` したらこのテストが自動的に発火するようにします。

GitHub と Travis CI との連携方法については適当に調べてください。（なれれば10秒の作業ですw）

## Travis CI で毎日定期的に実行するようにする

Travis CI には Cron Jobs という機能があり、これを使用すると毎日定期的に実行してくれます。

![](https://www.evernote.com/l/ABU-HB0kugZAp4x8uV4hht4Xxj1uR16imx0B/image.png)

WP-CLI と組み合わせると、このステータスを自動的にチェックして WordPress 上でのプラグインのアップデートを自動化することもできます。

こうすることで、互換性のトラブルがあれば自動アップデートを止めて、問題がなければ自動アップデートというワークフローを自動化することができます。

互換性の問題があれば Travis CI がメールで通知してくれますので安心ですよね。

## サンプルプラグイン

https://github.com/tarosky/redirect-for-contact-form-7