wp-envでWordPressテーマ/プラグインのユニットテストやE2Eテストを構築

WordPress開発で便利なあれこれを使える wp-cli のコマンドにプラグイン用のテストを準備する wp scaffold plugin-tests があるのですが、2018年にリポジトリがアーカイブされてしまっていたようです。

https://github.com/benbalter/wordpress-plugin-tests/

コマンド実行をすることは出来るのですが、そのままではユニットテストの実行をする事はできず、対処方法を導入してもブロックエディタのテストなどには対応していなかったのであまり深追いしない方がいいなと諦めました。

他の方法は無いのかと調べたところ @wordpress/env を活用した開発環境でのテストが主流になっているようなのでテスト方法をまとめてみました。

WordPressのテストコードについてはあまり情報もなく、ある程度定番の物ができたとしてもすぐに新しい物が出てくるのでなるべく公式の流れに添いつつ、カスタマイズもしないで使えるように構築していきます。

なお、プラグイン開発を対象として紹介していきますが、テーマ開発でも使用できる内容となっております。

@wordpress/envとは

dockerを使用した開発環境を構築するnpmパッケージ。

# グローバル環境にインストール
$ npm -g i @wordpress/env

# プロジェクト内にインストール
$ npm i @wordpress/env --save-dev

を実行することで

wp-env start

でdockerでWordPress開発環境 ( http://localhost:8888 ) とテスト環境 ( http://localhost:8889 ) が作られます。

プラグイン開発を行っているプロジェクトであらかじめ有効にさせる方法は .wp-env.json を使用します。

{
	"plugins": [ "." ],
	"config": {
		"WP_DEBUG": true
	}
}

後述する wp-scripts test-e2e はこの wp-env を使う事を想定されているので、特に理由がなければ使う事をオススメします。

WordPressプラグインをテストできる種類について

毎回ブラウザアクセスすることで確認できる範囲なのであればテストコードは不要になるかとは思いますが、テストコードがあると作業削減に繋がり複雑な処理を実装する助けになります。

テストコードを使用したテストの種類については以下を実装する事が可能です。

  • ブラウザを使用した表示内容の精査 (EndToEnd = E2Eテスト)
  • jsコードのユニットテスト
  • PHPコードのユニットテスト (phpunitテスト)

この記事で紹介するのは E2Eテストとphpunitテストになります。

PHPコードのユニットテストを作成

WordPress SEOプラグインとして人気な Yoast が公開してくれているプラグインを使用します。

https://github.com/Yoast/wp-test-utils

こちらの公式情報に沿って導入していきます。

composer require --dev yoast/wp-test-utils
composer require --dev phpunit/phpunit yoast/phpunit-polyfills

インストールできたバージョンはこちら

{
    "require-dev": {
        "yoast/wp-test-utils": "^1.2",
        "phpunit/phpunit": "^9.6",
        "yoast/phpunit-polyfills": "^1.1"
    }
}

以下のファイルを作成します

  • phpunit.xml.dist
  • phpunit/bootstrap.php
  • phpunit/class-example-test.php
<?xml version="1.0"?>
<phpunit
	bootstrap="phpunit/bootstrap.php"
	backupGlobals="false"
	colors="true"
	convertErrorsToExceptions="true"
	convertNoticesToExceptions="true"
	convertWarningsToExceptions="true"
	>

	<testsuites>
		<testsuite name="testing">
			<directory suffix="-test.php">./phpunit/</directory>
		</testsuite>
	</testsuites>
</phpunit>
<?php

# サンプルのbootstrapを適応 https://github.com/Yoast/wp-test-utils#using-the-bootstrap-utilities
# プラグインのパスを置換 plugin-name/main-file.php -> example-plugin/example-plugin.php

use Yoast\WPTestUtils\WPIntegration;

if ( getenv( 'WP_PLUGIN_DIR' ) !== false ) {
    define( 'WP_PLUGIN_DIR', getenv( 'WP_PLUGIN_DIR' ) );
}

$GLOBALS['wp_tests_options'] = [
    'active_plugins' => [ 'plugin-name/main-file.php' ],
];

require_once dirname( __DIR__ ) . '/vendor/yoast/wp-test-utils/src/WPIntegration/bootstrap-functions.php';

/*
 * Bootstrap WordPress. This will also load the Composer autoload file, the PHPUnit Polyfills
 * and the custom autoloader for the TestCase and the mock object classes.
 */
WPIntegration\bootstrap_it();

if ( ! defined( 'WP_PLUGIN_DIR' ) || file_exists( WP_PLUGIN_DIR . '/plugin-name/main-file.php' ) === false ) {
    echo PHP_EOL, 'ERROR: Please check whether the WP_PLUGIN_DIR environment variable is set and set to the correct value. The integration test suite won\'t be able to run without it.', PHP_EOL;
    exit( 1 );
}
<?php

use Yoast\WPTestUtils\BrainMonkey\TestCase;

class ExampleTest extends TestCase {

	/**
	 * @test
	 */
	public function example() {
		$this->assertTrue( true );
	}
}

wp-env で作成されるテスト環境でphpunitを実行します。

$ wp-env run tests-cli --env-cwd='wp-content/plugins/example-plugin/' vendor/bin/phpunit
ℹ Starting 'vendor/bin/phpunit' on the tests-cli container. 

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.
PHPUnit 9.6.15 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 00:00.175, Memory: 40.50 MB

OK (1 test, 1 assertion)
✔ Ran `vendor/bin/phpunit` in 'tests-cli'. (in 1s 834ms)

上記コマンドを package.json に記載しておくと実行しやすくなります。

{
	"scripts": {
		"test:php": "wp-env run tests-cli --env-cwd='wp-content/plugins/example-plugin/' vendor/bin/phpunit"
	}
}

E2Eテストの作成

プログラムの実行でブラウザ操作を行い、表示内容を確認する手法です。スクリーンショットも作成してくれるので、実行結果を画像としても確認できるようになるのでプラグイン開発以外でも活用が期待できます。

こちらは wp-env で作成したテスト環境 ( http://localhost:8889 ) にアクセスしてE2Eテストを実行するので、あらかじめ wp-env start で環境を立ち上げておきます。

@wordpress/scripts パッケージで使用できる wp-scripts test-e2e コマンドを使用します。こちらは Jest APIを使用したテストです。

注意: 現在 (2023年12月) は Jest API から Playwright を使用したE2Eテストへ移行している期間の最中になり、将来的には変更される予定です。ですが、あくまで途中でありPlaywrightでのテストは大きな変更が入る可能性もあるため、安定している Jest APIを使用したE2Eテストを紹介していきます。

$ wp-scripts test-e2e

# ドキュメントで指定される package.json での導入済みであれば以下と同様
$ npm run test:e2e

実行した場合には以下の表示になります。

% npm run test:e2e 

> example-plugin@0.1.0 test:e2e
> wp-scripts test-e2e

Downloading Chromium r982053 - 117.4 Mb [====================] 100% 0.0s 
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /path/to/example-plugin
  162 files checked.
  testMatch: **/specs/**/*.[jt]s?(x), **/?(*.)spec.[jt]s?(x) - 0 matches
  testPathIgnorePatterns: /node_modules/ - 162 matches
  testRegex:  - 0 matches
Pattern:  - 0 matches

テストファイルを探しているパターンも表示されているので好きな場所に設置しましょう。今回は /specs/ ディレクトリを作成して配置していきます。

テスト用のライブラリを導入する必要もあり、@wordpress/e2e-test-utils を使用します。 ( playwright版は @wordpress/e2e-test-utils-playwright )

npm i -D @wordpress/e2e-test-utils

サンプルとしてプラグインがアクティブになっているか確認するコードがこちら

import { loginUser, visitAdminPage } from "@wordpress/e2e-test-utils";

describe("plugin active", () => {
	it("verifies the plugin is active", async () => {
		await loginUser();
		await visitAdminPage("plugins.php");

		const pluginSlug = "example-plugin";
		const activePlugin = await page.$x(
			'//tr[contains(@class, "active") and contains(@data-slug, "' +
				pluginSlug +
				'")]',
		);

		expect(activePlugin?.length).toBe(1);
	});
});

正常に実行できれば以下のようになります。

$ npm run test:e2e

> example-plugin@0.1.0 test:e2e
> wp-scripts test-e2e

Chromium is already in /path/to/example-plugin/node_modules/puppeteer-core/.local-chromium/mac-982053; skipping download.
 PASS  specs/plugin-active.js (8.973 s)
  plugin active
    ✓ verifies the plugin is active (8602 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.007 s
Ran all test suites.

最後に

以上、WordPress開発でのテストコードを作成する方法を紹介しました。

他にもjsコードのユニットテストを導入する場合には以下の情報が参考になるかと思われます。

なお、この記事の情報を実際に適応したWordPressプラグインを公開しているので、こちらを参考にしていただくこともできます。

https://github.com/soramugi/beastfeedbacks

今回も参考になりましたら幸いです。

投稿者


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA