assert_selectでCSSセレクタを使う

Ruby on Railsアプリケーションの統合テストは,ActionController::IntegrationTestクラスを継承して作成する。統合テストは,ユーザが行うアクションを想定してコードでシミュレーションを行い,結果としてアプリケーションが正しく振る舞うかどうかを確認するためのテストである。一般的にWebアプリケーションの場合は,操作の結果としての出力の形式がHTMLという比較的複雑な文字列であるため,正しい動作を行ったかどうかの検証は難しい部類に入る。

Railsの場合,レンダリングされたHTMLに対しての検証を行う際に便利なメソッドがいくつか提供されている。それがassert_selectメソッドだ。これを使うことにより,特定の要素がHTML文字列内に含まれているかどうか,要素の子として正しいテキストが出力されているかどうか,などを確認することができる。HTML文字列全体を検証することはせず,動的に変更される箇所のみを抜き打ちで確認するのが妥当なレベル。assert_selectはそんな確認について大きな威力を発揮してくれる。

例えば,データベースから取得したモデルがtable要素を使って出力されていることを考えてみよう。列見出しの行が1行あるとして,取得結果が5件であることを確認するには,Integration::Sessionオブジェクトに登録したメソッド内で,以下のようにすれば良い。

assert_select ‘tr’, 6

tr要素が6個存在することが上記のコードで確認できる。

assert_selectメソッドのシグネチャは,

  • assert_select(selector, equality?, message?)

  • assert_select(element, selector, equality?, message?)

と2つある。2つ目のelementは,検証する起点となる要素を指定するためのもので,element引数を指定しなければ,HTML文字列全体について検証対象となる。

selectorという引数は,上記のコード例では’tr’が指定されていた。この引数は,CSSのセレクタの仕様を使って記述することができる。例えば,td要素の子孫として含まれるdiv要素全てについて検証したい場合は,selector引数に’td div’と指定して,

assert_select ‘td div’ do |elements| elements.each do |element|

elementについて検証

end end

としてあげれば良い。

さて,そうなってくると,「CSSのセレクタで指定するの?完璧に要素を特定するなんて無理なんじゃね?」とお思いの方もいらっしゃることだろう。その疑問はごもっとも。しかし,以下の2点を実施すれば,ほぼ困ることはなくなると個人的に思っている。

  • そもそもCSSのセレクタの仕様は奥が深い。知らない仕様もあるはずなので,きっちり勉強する。

  • 要素を特定するために,レンダリング時に対象要素に対してid属性を付けておく。

CSSのセレクタの仕様は,僕も”tr td”(文脈セレクタ)や”h1 h2 h3”(タイプセレクタ),”.error”(クラスセレクタ)くらいしか知らなかったが,これ以外にもいくつかセレクタの仕様は存在している(CSS2になって増えた)。

  • 一意セレクタ(id属性値を指定) - 「h1#hoge」

  • 属性セレクタ(属性と値を指定) - 「a[target=”_blank”]」

  • 文脈セレクタの拡張(直接の子指定) - 「body > div」

他にもいくつかあるので,仕様を押さえておくと良いだろう。例えば,「 CSS 概要 | セレクタ」というページは,よくまとまって説明されているので,非常に参考になる。ここでは,IEやMozillaで動作検証をしていて「ダメじゃん」という結果が出ているが,Railsに搭載されているHTML:Selectorはちゃんと期待通りの動きをしてくれるっぽい。

それでもセレクタをどうするか悩むことを避けたい人は,一意セレクタをフル活用することを前提に,予めレンダリングされる要素に,テスト都合でid属性を付けておくのも手である。良識のあるWebデザイナや,見た目と情報の分離を突き詰めてしまう原理主義者にとっては,これはあり得ないことかもしれない。しかし,アプリケーションのテストができなければ,そもそも話にならない。現時点での現実解としては「あり」なのではないかと個人的には思っている。

ま,何はともあれ,Ruby on Railsの統合テストは非常に楽しいし,テストファーストでシナリオを書くことができれば,かなり高い品質を保ったアプリケーションを早期に手に入れることができるだろう。ただし,CSSセレクタに代表されるWebアプリケーションの基礎的な知識を有していることが前提条件なのは確か。基本をちゃんと押さえておくのは重要だな,と再確認させられた。

このエントリーをはてなブックマークに追加

関連記事

スマートスピーカーはもう終わったデバイス?

QMK FirmwareとRaspberry Pi PicoでSPLIT_USB_DETECTを使わない方法

40%キーボードに慣れるためにやったこと

Lunakey PicoでQMK Firmwareを動かしてみました

Googleアシスタント向け会話型アクションが1年後にシャットダウンされます