getByRole()を使ったボタン要素の取得方法

Testing Libraryで<button>要素に関するテストケースを書く場合、ボタン要素の取得はgetByRole()1を使うことをおすすめする。 getByRoleを使うと「〇〇ラベルのボタン要素」に対するテストであることを一目で例示できるためである。

getByRole()は各要素に紐づくWAI-ARIA role2を使って要素を取得する。WAI-ARIA3はWeb標準の仕様名で、roleはWAI-ARIAで定められた属性名である。このroleをクエリに指定できるのがgetByRole()の特徴である。

つまり、getByRole()でクエリを書くとWeb標準に則った指定名で「どの要素を取得してテストを書こうとしているか」が一目瞭然となる。

どのrole名を指定すれば良いかを確認するためには、mdn web docsを参照するとわかりやすい。ボタン名であれば ARIA: button role4ページを参照する。 通常のボタンはボタン内部にテキストが表示されている。これがnameに割り当たる。よって、button属性のname: ボタン内部のテキストという形で要素を指定すれば狙い通りに取得できる。

例えばボタン内部に「OK」と記載されているボタンがあるとする。

// ボタン要素
<button onClick={handleClick}>OK</button>

次のようにgetByRole()buttonroleを指定し、nameOKを指定すれば対象の要素を取得できる。

// OKボタンが存在するか
expect(content.getByRole("button", { name: "OK" })).toBeTruthy()

getByTextとの使い分け

ボタン内部のテキストはgetByText()でも取得できる。

// OKというテキストを持つ要素が存在するか
expect(content.getByText("OK")).toBeTruthy()

しかし、getByText()だけではOKというテキストを持つ要素が存在するかを検証しているように見える。 実際はOKラベルがついている<button>要素が存在するか、を検証したい。外れてはいないが、他に「OK」を持つテキスト要素が存在すると狙った要素が取得できない。 コードを閲覧せずに、何を取得したいかを表現できるクエリを選ぶと良い。