[basecamp/lexxy] テストコードから不要なsleepを削除し、Capybaraの自動待機機能を活用
背景
システムテストにおいて、sleepを用いた能動的な待機処理は、テストスイートの実行速度を低下させるだけでなく、信頼性の面でも問題がある。特に、非同期処理が完了するまでの待機時間が環境によって異なる場合、固定時間のsleepでは不十分なケースや、逆に過剰な待機時間となるケースが発生する。
Capybaraには組み込みヘルパーに自動待機機能が備わっており、これを適切に活用することで、より堅牢で高速なテストコードを実現できる。
実装された変更
1. エディタの値検証における待機処理の改善
従来は、エディタのプレーンテキスト値を検証する際に単純な等価比較を行っていた。
変更前:
def assert_editor_plain_text(value)
assert_equal value, find_editor.plain_text_value
end
変更後:
def assert_editor_plain_text(value)
wait_until { find_editor.plain_text_value == value }
end
def wait_until(timeout: Capybara.default_max_wait_time)
Timeout.timeout(timeout) do
sleep 0.05 until yield
end
end
この変更により、エディタの値が期待値になるまで自動的に待機するようになった。wait_untilヘルパーは、Capybaraのデフォルトタイムアウト時間を使用し、50ミリ秒間隔で条件をチェックする。
2. テストコードからsleepを削除
ファイルアップロード後の検証処理から不要なsleepが削除された。
変更前:
attach_file file_fixture("example.png") do
click_on "Upload file"
end
sleep 0.1
assert_editor_plain_text "[example.png]\n\n"
find("figcaption textarea").click.send_keys("Example Image")
find_editor.click
sleep 0.1
assert_editor_plain_text "[Example Image]\n\n"
変更後:
attach_file file_fixture("example.png") do
click_on "Upload file"
end
assert_editor_plain_text "[example.png]\n\n"
find("figcaption textarea").click.send_keys("Example Image")
find_editor.click
assert_editor_plain_text "[Example Image]\n\n"
assert_editor_plain_textが自動待機機能を持つようになったため、明示的なsleepが不要となった。
3. エディタハンドラーからのsleep削除
エディタの値設定や選択範囲の操作後のsleepも削除された。
def value=(value)
editor_element.set value
editor_element.execute_script "this.value = `#{value}`"
# sleep 0.1 を削除
end
def select(text)
# JavaScriptによる選択処理
# sleep 0.1 を削除
end
def select_all
# JavaScriptによる全選択処理
# sleep 0.1 を削除
end
技術的な利点
- 実行速度の向上: 固定時間の待機ではなく、条件が満たされ次第すぐに次の処理に進むため、テストの実行時間が短縮される。
- 信頼性の向上: 環境による処理速度の差異に左右されにくくなり、フレーキーなテストが減少する。
- 保守性の向上: 「なぜこのsleepが必要なのか」を考える必要がなくなり、コードの意図が明確になる。
残された課題
キー入力後の待機処理については、適切な代替手段が見つからなかったため、一部のsleepは残されている。この点については今後の改善が期待される。