単体テストとは?
そもそも単体テストとはなんぞや、という話ですが、「この関数は期待通りに動くのか?」をテストするものです。基本的にはメソッド・関数単位で行います。 この単体テストをGitHub ActionsなどのCI/CDに組み込むことで、「テストが通っている限りはその関数は壊れていない」と保証されます。もちろん、テストが正しいことが前提ですが。 PHPではPHPUnitが定番かつほぼ一択。たとえば、郵便番号を受け取ったら123-4567 のようなフォーマットで必ず返してくれる my_zip という関数を作ったとします。これが本当にいつも必ず動くのかをテストしたい場合は次のようなテストコードを書きます。
class Basic_Test extends WP_UnitTestCase {
public function test_zip() {
// ハイフンなしもなおるか?
$this->asertEquals( my_zip('1234567'), '123-4567' );
// 全角数字も受け入れる?
$this->asertEquals( my_zip('123ー4567'), '123-4567' );
// 桁が多い場合は仕様通りWP_Errorを返す?
$this->assertWPError( my_zip('1234567890') );
// .....
}
}
PHPUnit 9.6.24 by Sebastian Bergmann and contributors.
............................................. 45 / 45 (100%)
Time: 00:00.883, Memory: 58.50 MB
OK (45 tests, 156 assertions)
WordPressではどうやって実行しているのか
WordPressのコアは自動テストを導入しており、一連のテストスイートの中にPHPUnitが含まれています。現在はWordPressコアのリポジトリにコミットするとGitHub Actionsで一連のテストが走ります。
プラグインやテーマにどう組み込むか
上述したテストスイートはプラグインやテーマでも利用することができます。- WP-CLIのscaffoldコマンドを使う。必要なファイルが全部揃う。
- 上記でインストールされる install-wp-tests.sh とリポジトリに入れる(手動管理)
- wp-envを使う。Dockerが二個立ち上がるのだが、そのうち一個にはテストスイートが最初からインストールされている。
- PHPUnit: たしかPHPUnit 10以上には対応していないはず。PHPUnit Compatibility and WordPress Versions を参照のこと。
- yoast/phpunit-polyfills: 複数のPHPバージョンでPHPUnitを試したい時に必須。これを入れるとPHPUnitも対応したバージョンが自動ではいるはず? PHPUnit 11以上(なぜか10は除外)もサポートしています。
composer require --dev phpunit/phpunit
- 基本的な関数、クラスメソッドのテスト
- WordPressの機能と統合したテスト
どれだけテストを書くか
さて、リポジトリを見ると「テストコードが多いな」ということを感じるかもしれません。安全に倒す場合、テストコードはどんどん増えていきます。が、時間は有限なので、まずは1個でもいいからテストを書くことから始めましょう。 私はこれまで何十個もプラグインを公開してきたのですが、CI/CDにテストが組み込まれていると、少なくとも「構文エラーがあってプラグインを更新したら画面が真っ白になった」という事態を防ぐことができます。それだけでもテストを導入する意味があります。 その上でテストの優先順位を決めていくことが必要です。これは以前紹介したe2eテストでも同じです。- 書きやすい部分(価格計算やフォーマット関数)にテストコードを追加する
- そのプラグイン、テーマにとって核心的な部分をカバーしていく
- ただのラッパー関数
- WordPressのコアが保証している部分(WP_Queryを頑張ってテストしない)
テスタブルなコードを書く
一番大事なのはそもそもテスト可能なコードを書く、ということです。たとえば、投稿のときに何かをするフィルターフックを追加したとしましょう。次のようなパターンはよくあるのですが……add_action('save_post', function( $post_id ) {
// ここでダラダラ処理を書く
update_post_meta( $post_id, 'some_key', 'some_var' );
} );
add_action( 'save_post', function( $post_id ) {
// ここら辺で色々権限チェックを行う。投稿タイプのチェックとか。
if ( ! wp_verify_nonce( filter_input( INPUT_POST, '_mymodificationnonce' ), 'update_modification' ) ) {
return;
}
// 投稿IDを受け取って何らかの処理を加える関数を作っておく
my_modification_func( $post_id );
} );
// テスト対象にしやすい
class Mofidy_Test extends WP_UnitTestCase {
public function test_modification() {
// 投稿を作成
$post_id = self::factory()->post->create( [
'post_tile' => 'Hello World',
'post_status' => 'publish',
'post_content' => 'Lorem ipsum dolor',
] );
my_modification_func( $post_id );
// 結果を確認
$this->assertEquals( 'some_var', get_post_meta( $post_id, 'some_key', true ) );
}
}
*
以上でWordPressにおけるPHPUnitの採用方法の紹介は終わりです。テストを導入すれば安心してデプロイできますね。









