この記事は「Vektor WordPress Solution Advent Calendar 2020」の 12月11日の記事になります。

カスタムブロックを作成した経験があり、カスタムブロックの後方互換性の維持に苦しんでいる人が対象です。この記事のチュートリアルを通して、カスタムブロックの後方互換テストの実装方法を知ることができます。

こんにちは、ベクトルのオオハシです。
ベクトルでは主に VK Blocks / VK Blocks Pro の開発を担当しています。

VK Blocks もお陰様でユーザーが増えてきて、アクティブインストールが1万を超えました。
ありがたいことなのですが、後方互換性の維持にかなりのリソースをさいています。

カスタムブロックの後方互換の維持はかなり辛いです。

この課題を解決するために、Gutenbergに実装されていた後方互換テストを、VK Blocksに移植しました。

簡単に後方互換テストを実装できるようサンプルコードも弊社で公開しました。
ぜひご利用ください。

なには、ともあれサンプルコードを動かしてみましょう。

Block Test Kit クイックスタート

注意

テストを実装するには以下の要件満たす必要があります。

  • Block API version 2
  • WordPressモジュールの読み込みに、import を使用。
  • wp-scripts で ブロックをビルドしている。
  • 多少のブロックの構造変更は許容できる。

まず、サンプルコードをGitHubからクローンします。

git clone https://github.com/vektor-inc/block-test-kit.git && cd block-test-kit
npm install
npm start

上のコマンド完了後、http://localhost:8888/ にアクセスするとWordPressが立ち上がっています。

後方互換テスト実行します。

npm run test-unit

すると、下のように実行結果が出力されます。

PASS  test/integration/full-content/full-content.test.js
  full post content fixture
    ✓ block-test-kit__alert (19ms
    ✓ should be present for each block (1ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        4.333s
Ran all test suites matching /test\/integration\/full-content\/full-content.test.js/i.

これで、アラートブロックは後方互換を維持していることがテストできました。

Block Test Kit フォルダ構成

  • src: アラートブロックフォルダ
    • index.js、edit.js等 . . : ブロックに必要なファイル。
  • test: テストファイルフォルダ
    • e2e-tests/fixtures:
      • blocks: ブロックの各状態と比較するためのデータ(フィクスチャー)
        • block-test-kit__alert.html: 初期状態
        • block-test-kit__alert.parsed.json: 期待されるパース後の状態
        • block-test-kit__alert.json: ブロックオブジェクトの状態
        • block-test-kit__alert.serialized.html: パースしたブロックをserializeでシリアライズした状態
      • utils.js: テストに必要な関数
    • integration/full-content/full-content.test.js: 後方互換テストファイル
    • jest.config.js: Jest設定ファイル
  • babel.config.js: テスト用のバベル設定ファイル
  • block-test-kit.php: プラグイン本体
  • package.json: モジュール管理
  • wp-env.json, .editorconfig 等 . . .: 開発環境設定用ファイル。

※ テストに必須なファイルにはマーカーを引いています

1. ブロックに機能追加

実際のカスタムブロック開発では、どんどん機能を追加していきます。

例としてタイトルを追加します。
<h3>{__('Alert Block', 'block-test-kit')}</h3> を edit.js と save.js に追加します。

import { __ } from '@wordpress/i18n';
import { PanelBody, SelectControl } from '@wordpress/components';
import { Fragment } from '@wordpress/element';
import { InspectorControls, RichText, useBlockProps } from '@wordpress/block-editor';

import './editor.scss';

export default function AlertEdit({ attributes, setAttributes }) {

	const { style, content } = attributes;

	const blockProps = useBlockProps( {
		className: `alert alert-${style}`,
	} );

	return (
		<Fragment>
			<InspectorControls>
				<PanelBody title={__('Style Settings', 'block-test-kit')}>
					<SelectControl
						value={style}
						onChange={(value) => setAttributes({ style: value })}
						options={[
							{ label: __('Info', 'block-test-kit'), value: 'info' },
							{
								label: __('Danger', 'block-test-kit'),
								value: 'danger',
							},
						]}
					/>
				</PanelBody>
			</InspectorControls>
			<div { ...blockProps }>
				<h3>{__('Alert Block', 'block-test-kit')}</h3>  // 👈 タイトル追加
				<RichText
					tagName="p"
					onChange={ (value) => setAttributes({ content: value }) }
					value={content}
				/>
			</div>
		</Fragment>
	);
}
import { __ } from '@wordpress/i18n';
import { RichText, useBlockProps } from '@wordpress/block-editor';

export default function save({ attributes }) {

	const { style, content } = attributes;

	return (
		<div { ...useBlockProps.save( { className: `alert alert-${style}`} ) }>
			<h3>{__('Alert Block', 'block-test-kit')}</h3>  // 👈 タイトル追加
			<RichText.Content tagName={'p'} value={content} />
		</div>
	);
}

上の修正後、試しに下のコマンドを打ってみてください。

npm run test-unit

するとテストがこけます。
後方互換処理を書いていないため、壊れます。というか壊れるのが正しいです。

2. ブロックに後方互換処理を追加

index.jsで後方互換処理を追加します。deprecated のコメントアウトを外します。

export const settings = {
	title: __('Alert', 'block-test-kit'),
	icon: 'smiley',
	save,
	edit,
	// deprecated, 👈 コメントアウトを外す
};

3. 後方互換テスト更新

3-1. 古い後方互換テストを作成

ルートディレクトリで以下のコマンドを実行して、フィクスチャーの名前を変更します。

mv test/e2e-tests/fixtures/blocks/block-test-kit__alert.html test/e2e-tests/fixtures/blocks/block-test-kit__alert__deprecated.html

この時、作成するファイル名を block-test-kit__alert__deprecated-0_84_1.html みたいにバージョン番号をつけておくと幸せになれそう…。

3-2. 新しく変更したバージョンの後方互換テスト作成

下のコマンドを実行して、最新版のフィクスチャーを作成します

touch test/e2e-tests/fixtures/blocks/block-test-kit__alert.html 

block-test-kit__alert.html を作成後、http://localhost:8888/ にアクセスしてAlert ブロックを挿入します。

Alertブロック挿入

サイドバーから、コードエディターに切り替えます。Alertブロックの内容をコピーし、先ほど作った block-test-kit__alert.html にペーストします。

Alertブロックをコードエディターで開く
<!-- wp:block-test-kit/alert -->
<div class="wp-block-block-test-kit-alert alert alert-info"><h3>Alert Block</h3><p>Hello World!</p></div>
<!-- /wp:block-test-kit/alert -->

最新版のフィクスチャーを生成します。

npm run fixtures:regenerate test/integration/full-content/full-content.test.js

すると、以下のファイルが生成されます。

  • block-test-kit__alert.json
  • block-test-kit__alert.parsed.json
  • block-test-kit__alert.serialized.html

これでもう一度、テストを実行します。

npm run test-unit

すると以下のように、最新のバージョンのブロックで、過去に保存したブロックのデータを開いても壊れない事がテストできました。

 PASS  test/integration/full-content/full-content.test.js
  full post content fixture
    ✓ block-test-kit__alert (18ms)
    ✓ block-test-kit__alert__deprecated (9ms)
    ✓ should be present for each block (1ms)

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        2.564s, estimated 4s

つまり、

このテストを実装する事で、

過去の全バージョンのブロックが、最新版と互換性がある事を

コマンド一発で確認できます!

参考

サンプルコードに入ってるファイルはGutenberg本体のものを改変して使っています。

最後に

どうだったでしょうか?
この互換テストと GitHubActionsを組み合わせると、プルリクを送った時に、過去バージョンに対しての後方互換を確認できます。

これでかなり楽になりますね。

では、Have a happy Dev life!

Follow me!

この記事を書いた人

大橋直記
大橋直記
和歌山在住のWordPress Plugin Developer、ベクトルでは主にGutenbergのカスタムブロックプラグインの開発を担当しています。

Core Contributor(5.1)

初心者でも簡単!無料WordPressテーマ

100%GPL / 商用利用可能

Lightning は WordPress公式ディレクトリに登録されているカスタマイズ性の高いテーマです。
デモデータも配布されているので、ビジネスサイトの雛形が数分でセットアップできます。

VWSオンラインコミュニティー

オンラインコミュニティでは、より良いテーマ・プラグイン開発のため、機能改善・追加要望などの書き込み大歓迎です!
ユーザー同士の交流や意見交換の場としてもお気軽にご参加ください。
※質問はフォーラムでのみ対応となります。