WordPressのプラグインをCodeceptionを使ってテストする


## はじめに ##
WordPressプラグインのテストをCodeceptionを使ってテストする際の手順をまとめました。実際に作成したものを[GitHub](https://github.com/Ippey/wp-codecept)に公開しています。テストの内容はこれをもとに記載しています。


## Codeceptionとは ##
[Codeception](http://codeception.com)は、PHPのテストツールのひとつです。ユニットテストの他に、ブラウザを使った振る舞いテストや、APIのテストをおこなうことができます。

## Codeceptionを使うメリット ##
WordPressのプラグインをテストする際に、Unitテストはphpunit、実ブラウザでのテストはSeleniumや、実際に動かしてテストしてみたりと、各アプリケーションを切り替えてテストすることになり、結構面倒ですが、Codeceptionを使うことでコマンド１発で両方のテストを行うことができます。Codeceptionのテストは記述しやすいので、テストケースの作成コストも下がると思います。

## 前提条件 ##
以下がインストール＆起動されている必要があります。また、以降の説明・コマンドはMacで実行確認しています。

- PHP
- WordPress
- wp-cli
- MySQL
- selenium-server + chromedriver


## プラグイン作成 ##
プラグインの足場（scaffold）を作成します。

	cd /path/to/wordpress/wp-contents/plugins
	wp scaffold plugin <プラグイン名>

scaffold作成後、実際のプラグインのプログラムを作成していきます。

## テスト用WordPressの設定 ##
上記プラグインscaffoldを作成した際にテスト用WordPress設定用シェルがbinディレクトリ内に出来上がっていますので、それを実行します。

	cd /path/to/wordpress/wp-contents/plugins/<プラグイン名>
	./bin/install-wp-test.sh <DB_NAME> <DB_USER> <DB_PASS> <DB_HOST> <WordPressのバージョン>

## Codeceptionのインストール ##
次にCodeceptionのインストールを行います。プラグインディレクトリ内で以下を実行します。

	wget http://codeception.com/codecept.phar


プラグインディレクトリ内に、"codecept.phar"ができていれば成功です。

## Codeceptionの設定 ##
### bootstrapの実行 ###
以下を実行して、Codeceptionで利用するファイル一式を作成します。

	php codecept.phar bootstrap

### _bootstrap.phpの設定 ##
上記コマンドを実行すると、testsディレクトリ内に_bootstrap.phpが作成されます。中身は空の状態ですが、テストするためにはWordPress用の設定が必要になります。設定はscaffold作成時に、bootstrap.php内に記載されていますので、その内容をコピーします。

	cd tests
	cp bootstrap.php _bootstrap.php


これで、テストの準備が整いました。

## Unitテスト作成 ##
まずはUnitテストを作成していきます。Codeceptionではコマンドでテスト用のファイルの作成できます。

	php codecept.phar generate:phpunit unit <テストクラス名>

上記コマンドで、tests/unit/内にファイルが作成されます。作成されたファイルはPHPUnitフォーマットになっていますので、微調整を行います。

```php:tests/unit/SampleTest.php
<?php
// 親クラスをWP_UnitTestCaseに変更
class SampleTest extends WP_UnitTestCase
{

	// protectedをpublicに変更
    public function setUp()
    {
    }

	// protectedをpublicに変更
    public function tearDown()
    {
        parent::tearDown();
    }

    // tests
}
```

## ブラウザテスト作成 ##
### 設定 ###
CodeceptionのAcceptanceTestというものを利用することでブラウザでのテストが可能になります。デフォルトはPHPBrowserを利用するようになっていますが、seleniumと連携することもできます。今回はChromeでのテストの設定にしてみます。

```ruby:tests/acceptance.suite.yml
# Codeception Test Suite Configuration
#
# Suite for acceptance tests.
# Perform tests in browser using the WebDriver or PhpBrowser.
# If you need both WebDriver and PHPBrowser tests - create a separate suite.

class_name: AcceptanceTester
modules:
    enabled:
        - WebDriver:
        - \Helper\Acceptance
    config:
		url: http://localhost/wordpress
		browser: 'chrome'

```

### テストの作成 ###
Unitテストと同じくコマンドでファイルを作成することができます。

	php codecept.phar generate:cest acceptance <テスト名>

できあがったファイルで、今回は管理画面のダッシュボード上に期待通りのメッセージが出ているかテストしてみます。

```php:tests/acceptance/SampleCest.php
<?php
use \AcceptanceTester;

class SampleCest
{
    public function _before(AcceptanceTester $I)
    {
        // 最初に管理画面にログインします。
        $I->amOnPage("/wp-login.php");
        $I->fillField("#user_login", 'admin');
        $I->fillField("#user_pass", 'admin');
        $I->click("#wp-submit");
    }

    public function _after(AcceptanceTester $I)
    {
    }

    // tests
    public function testRender(AcceptanceTester $I)
    {
        $I->canSee("hogehoge");
    }
}

```

## テスト実行！ ##
これで、テストの設定は完了です。
では、テストを実行してみましょう。

	php codecept.phar run

```
$ php codecept.phar run
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.
Codeception PHP Testing Framework v2.1.4
Powered by PHPUnit 4.8.18 by Sebastian Bergmann and contributors.
PHP Warning:  The use statement with non-compound name 'AcceptanceTester' has no effect in /Users/user/git/wp-codecept/tests/acceptance/WpCodeceptCest.php on line 2

Warning: The use statement with non-compound name 'AcceptanceTester' has no effect in /Users/user/git/wp-codecept/tests/acceptance/WpCodeceptCest.php on line 2

Acceptance Tests (1) -----------------------------------------------------------
Test render (SampleCest::testRender)                                  Ok
--------------------------------------------------------------------------------

Functional Tests (0) ------------------------
---------------------------------------------

Unit Tests (1) ------------------------------
SampleTest::testSay                Ok
---------------------------------------------


Time: 1.84 seconds, Memory: 35.00Mb

OK (2 tests, 2 assertions)

```

テスト結果がOKになっていればテスト合格です。
(上記結果は、PHPBrowserで実行しています)
コマンド実行１発でUnitテスト、ブラウザテストの両方を行うことができました。
ちなみに、それぞれわけて実行したい場合は

	php codecept.phar run unit
	php codecept.phar run acceptance

でUnitテストのみ、ブラウザテストのみを行うことができます。
さらに

	php codecept.phar run unit SampleTest.php

とすることで、指定のファイルのみ実行することができます。

## 最後に ##
WP_UnitTestCaseやCodeceptionでのテスト記述については、それぞれドキュメントをご覧ください。CodeceptionのAcceptanceテストは、WordPress以外でも役立つと思いますので、是非一度遊んでみてください。