WP Unit Test Sample
WordPress plugin & theme unit test sample environment using @wordpress/env
★ 0stars
0forks
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/hrkd/wp-unit-test/archive/refs/heads/main.zipWordPress テーマ/プラグインの PHPUnit テスト環境(@wordpress/env ベース)。
前提条件
- Docker Desktop (起動済み)
- Node.js 18 以上
セットアップ
# 1. リポジトリ取得
git clone <repo-url> wp-unit-test
cd wp-unit-test
# 2. npm 依存をインストール(wp-env が入る)
npm install
# 3. WordPress + MySQL コンテナを起動(初回は数分かかる)
npm run env:start
# 4. コンテナ内で composer install を実行(PHPUnit が入る)
npm run composer:install
# 5. テスト実行
npm test
成功すると testdox 形式で仕様書ライクに出力されます:
サンプルプラグイン
✔ 名前指定なしで "Hello, World!" を返す
...
テーマ表示ロジック
✔ 読了時間: 日本語 1200 文字は 2 分(600cpm 換算)
✔ 抜粋: 絵文字を 1 文字としてカウントする
✔ パンくず: 3 階層の祖先を順番通りに返し、末端だけ url が空
...
OK (19 tests, 27 assertions)
起動中のサイト
| 用途 | URL | 認証 |
|---|---|---|
| 開発サイト | http://localhost:8888 | admin / password |
| テストサイト | http://localhost:8889 | admin / password |
よく使うコマンド
| コマンド | 用途 |
|---|---|
npm test |
全テスト実行(testdox 形式・色付き) |
npm run test:dots |
旧来のドット表記で実行 |
npm run test:filter -- Test_Sample::test_sum |
特定テストのみ |
npm run env:stop |
コンテナ停止 |
npm run env:start |
コンテナ再開 |
npm run env:destroy |
コンテナ + DB を完全破棄 |
npx wp-env run cli wp plugin list |
コンテナ内で wp-cli 実行 |
ディレクトリ構成
.
├── .wp-env.json # WP / PHP バージョン、マウント設定
├── composer.json # PHPUnit + polyfills
├── package.json # wp-env と npm scripts
├── phpunit.xml.dist # PHPUnit 設定
├── wp-unit-test.php # サンプルプラグイン本体
├── themes/
│ └── wp-unit-test-theme/ # サンプルブロックテーマ
│ ├── style.css / theme.json
│ ├── templates/ parts/
│ └── inc/
│ └── display.php # テスト対象の表示ロジック
└── tests/
├── bootstrap.php # WP テストスイートのロード
├── test-sample.php # プラグイン側テスト
└── test-theme-display.php # テーマ側テスト
サンプルテストの特長
WP のユニットテストには「DB を使わない純粋関数」から「factory で投稿を組み立てる統合テスト」まで段階があります。同梱の 3 種類はそれぞれ違う側面をデモしています。
| # | 対象関数 | 種別 | 何を学べるか |
|---|---|---|---|
| 1 | wputtheme_reading_time |
純粋計算 | 境界条件のテスト設計(空文字、負値、画像加算、HTML 除去) |
| 2 | wputtheme_excerpt |
WP API 利用 + 文字列処理 | wp_strip_all_tags を介した HTML 除去、マルチバイト・絵文字の mb_substr 挙動 |
| 3 | wputtheme_breadcrumb |
DB + factory | self::factory()->post->create() で親子投稿を生成し階層を検証。WP_UnitTestCase の真価(テストごとに DB ロールバック) |
それぞれの「目玉アサーション」
1. 読了時間 — 純粋関数なので入力 → 出力を素直に検証。日本語 600cpm 換算の妥当性、画像加算ロジック、最低 1 分保証などを 1 行で確認できる。
// 1200 文字 = 2 分、画像 5 枚で +1 分などを直接検証
$this->assertSame( 2, wputtheme_reading_time( str_repeat( 'あ', 1200 ) ) );
$this->assertSame( 2, wputtheme_reading_time( str_repeat( 'a', 600 ), 5 ) );
2. 抜粋 — WP の API(wp_strip_all_tags)に依存しているため、純粋関数ではあるが WP テストブートストラップが必須。マルチバイト・絵文字のような「やりがちなバグ」を網羅。
// 絵文字を 1 文字としてカウントできているかは要注意ポイント
$this->assertSame( '🎉🎊…', wputtheme_excerpt( '🎉🎊🎈テスト', 2 ) );
3. パンくず — factory で 3 階層の親子投稿をテスト内で生成。実 DB は空でも get_post_ancestors や get_permalink が機能することを検証できる。テスト終了時に DB は自動ロールバックされるので副作用ゼロ。
$grandparent = self::factory()->post->create([ 'post_type' => 'page', 'post_title' => 'Company' ]);
$parent = self::factory()->post->create([ 'post_parent' => $grandparent, ... ]);
$child = self::factory()->post->create([ 'post_parent' => $parent, ... ]);
$result = wputtheme_breadcrumb( $child );
$this->assertSame( ['Company', 'Team', 'Hiroki'], wp_list_pluck( $result, 'name' ) );
選定基準
| 観点 | 1. 読了時間 | 2. 抜粋 | 3. パンくず |
|---|---|---|---|
| DB 必要 | ❌ | ❌ | ⭕ |
| WP 関数を使う | ❌ | ⭕ (wp_strip_all_tags) |
⭕ (get_post_ancestors 他) |
| factory を使う | ❌ | ❌ | ⭕ |
| 速度 | 最速 | 速い | やや遅い(投稿生成のオーバーヘッド) |
| 主な失敗源 | 計算式の境界 | 文字エンコーディング | 親子構造の組み立てミス |
トラブルシューティング
| 症状 | 対処 |
|---|---|
Could not find /wordpress-phpunit/... |
npm run env:start でコンテナが起動しているか確認 |
vendor/bin/phpunit: not found |
npm run composer:install を実行 |
| ポート 8888/8889 が衝突 | .wp-env.json に "port": 8898 などを追加 |
| 環境がおかしい | npm run env:destroy && npm run env:start でリセット |