[basecamp/lexxy] テストコードのリファクタリング: assert_editor_html とブロック形式のアサーション導入
変更の背景
このPRでは、lexxy(リッチテキストエディタ)のシステムテストコード全体をリファクタリングし、テストの可読性と保守性を向上させています。従来の assert_equal_html によるHTML文字列の直接比較に加え、Capybaraのセレクタを活用したブロック形式のアサーションを導入することで、より柔軟で意図が明確なテストコードを実現しています。
主な変更内容
1. assert_editor_html ヘルパーの導入
従来の assert_equal_html を置き換える新しいヘルパーメソッド assert_editor_html が追加されました。このメソッドは2つの使い方をサポートします。
従来の文字列比較形式
# 変更前
assert_equal_html "<p>Hello</p><p>there</p>", find_editor.value
# 変更後
assert_editor_html "<p>Hello</p><p>there</p>"
新しいブロック形式
# 変更後
assert_editor_html do
assert_selector "p", text: "Hello"
end
ブロック形式では、Capybaraの強力なセレクタAPIを活用できるため、特定の要素の存在確認や属性チェックが容易になります。
2. within_table ヘルパーの追加
テーブル関連のテストを簡潔に記述するための within_table ヘルパーが追加されました。これにより、テーブル内の要素に対するアサーションがより読みやすくなります。
# 変更前
html = find_editor.value
assert_match(/Test Cell/, html)
assert_match(/<table>.*?Test Cell.*?<\/table>/m, html)
# 変更後
within_table do
assert_selector "td", text: "Test Cell"
end
3. より表現力の高いアサーション
ブロック形式を活用することで、複雑な条件のテストがより明確に表現できるようになりました。
# テーブルのヘッダー行を確認
header_row = "tr:has(th + th + th)"
single_hr_row = "tr:has(th + td + td)"
within_table do
assert_selector header_row, count: 1
assert_selector single_hr_row, count: 2
end
この例では、CSSセレクタを使用してテーブルの構造を厳密にチェックしています。従来の正規表現ベースのアサーションと比較して、テストの意図が一目で理解できます。
4. ネガティブアサーションのサポート
ブロック形式では、要素が存在しないことを確認する assert_no_selector も使用できます。
assert_editor_html do
assert_text "**there**"
assert_no_selector "strong", text: "there"
end
これにより、「Markdownが変換されていないこと」といった否定的な条件も明確に表現できます。
実装の詳細
assert_editor_html の実装は以下の通りです。
def assert_editor_html(expected = nil, &block)
if block
Capybara.string(find_editor.value).instance_exec(&block)
else
wait_until { normalize_html(find_editor.value) == normalize_html(expected) }
end
rescue Timeout::Error
assert_equal normalize_html(expected), normalize_html(find_editor.value)
end
ブロックが渡された場合は、エディタの値を Capybara.string でラップし、ブロック内でCapybaraのマッチャーが使えるようにしています。ブロックがない場合は従来通りHTML文字列を正規化して比較します。
テストパフォーマンスへの影響
PR内で明記されている通り、このリファクタリングによるテスト実行時間への影響はありません。変更前後でテスト全体の実行時間は約45秒で安定しています。
技術的な利点
- 保守性の向上: HTML構造の変更に対してテストが柔軟になり、不要な修正が減少
- 可読性の向上: テストの意図が明確になり、レビューや理解が容易に
- 表現力の向上: Capybaraの豊富なマッチャーを活用でき、複雑な条件も簡潔に記述可能
- 一貫性の確保: テストコード全体で統一されたパターンを使用
このリファクタリングは、テストコードの品質向上における優れた実践例と言えます。特に、既存のAPIを破壊せずに新しい使い方を追加している点は、段階的な移行を可能にする設計として評価できます。