テストボタンのみのコンポーネントをテスト
import React from 'react';
import './App.css';
function App() {
return (
<div>
<button>TEST_BUTTON</button>
</div>
);
}
export default App;
このボタンのコンポーネントをテストする。
screen.getByText で取得。
https://testing-library.com/docs/queries/about/#textmatch-examples
一番シンプル。スクリーンのテキストからエレメントを取得する
test('renders App Text', () => {
render(<App />);
const appTextElement = screen.getByText('TEST_BUTTON');
expect(appTextElement).toBeInTheDocument();
});
文字列から取得。
PASS src/App.test.tsx
App
✓ renders App Text (36 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.845 s, estimated 2 s
当然パス。
同じ文字列が複数あるコンポーネントでテストする
<div>
<button>TEST_BUTTON</button>
<p>TEST_BUTTON is over there</p>
</div>
次は複数あるパターンでテストする
これも先ほどのコードでパスできる。
describe('App', () => {
test('renders App Text', () => {
render(<App />);
const appTextElement = screen.getByText('TEST_BUTTON');
expect(appTextElement).toBeInTheDocument();
screen.debug(appTextElement)
});
})
debug を入れてみると
renders App Text'
console.log
<button>
TEST_BUTTON
</button>
/Users/kaede/testing/src/App.test.tsx:14:12
12 | const appTextElement = screen.getByText('TEST_BUTTON');
13 | expect(appTextElement).toBeInTheDocument();
> 14 | screen.debug(appTextElement)
最初にあった button の方のみが選択されている。
複数ある場合は、最初にヒットした方がエレメントとして取得されることがわかった。
getByRole でエレメントを取得する
一つしかないロールから取得する
const appTextElement = screen.getByRole('button');
WAI_ARIA という基準で定められている HTML の役割、role でもエレメントを取得できる。
複数のボタンロールの要素がある場合に ボタンロールの指定だけだと失敗する
<div>
<button>TEST_BUTTON</button>
<button>SUB_BUTTON</button>
<p>TEST_BUTTON is over there</p>
</div>
しかし、このように button が複数ある場合に button ロールから取ろうとすると
TestingLibraryElementError: Found multiple elements with the role "button"
複数のボタンロールがあるからとエラーになる。
getByText と違って最初のものを取得したりはしない。
複数のボタンロールから name 指定で特定のロールを取得
screen.getByRole('button', {name: 'TEST_BUTTON'});
なのでこうやってタグの中身を name として指定すれば取得することができる。
getByRole では hidden や presentation ロールの要素は除外される
https://testing-library.com/docs/queries/byrole#options
<div>
<button role="presentation">presentation button</button>
<button>SUB_BUTTON</button>
<p>TEST_BUTTON is over there</p>
</div>
また、使わない方のボタンを hidden や presentation のロールにしておけば、アクセスから弾いてくれる。
このコードでは SUB_BUTTON のみが getByRole('button') で選択される。
getByRole のそのほかの role の詳細要素
https://testing-library.com/docs/queries/byrole#options
aria-hidden
aria-selected
aria-checked
aria-current
aria-pressed
aria-expanded
などで指定できる。
getAllByRole と map でヒットする複数のエレメントの存在を確認する
<div>
<button role="presentation">presentation button</button>
<button>SUB_BUTTON</button>
<div role="button">TEST_BUTTON is over there</div>
</div>
このように複数ある場合は
const appTextElement = screen.getAllByRole('button');
getAllByRole で取得できる。
しかしこれは配列なので toBeInTheDocument で確認するとエラーが出る。
test('renders App Text', () => {
render(<App />);
const appTextElement = screen.getAllByRole('button');
appTextElement.map( element => {
screen.debug(element)
expect(element).toBeInTheDocument();
} )
});
なので中身の配列に一つずつ document の中にあるか確認を取れば大丈夫。
console.log
<button>
presentation button
</button>
console.log
<button>
SUB_BUTTON
</button>
console.log
<div
role="button"
>
TEST_BUTTON is over there
</div>
PASS src/App.test.tsx
App
✓ renders App Text (55 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.61 s, estimated 2 s
全て見つかっている。
まとめ
getByText ではヒットした最初の一つが選択される
複数あってもエラーが出ない
getByRole では複数ヒットするとエラーが出る
name や aria-checked などの他の詳細で絞り込める
getAllByRole でヒットしたものを全て取り込んで、map して一つずつ document にあるかテストするのもあり。
次にやること
https://jestjs.io/ja/docs/using-matchers
toBe, toEqual, toContain
toHaveBeenLastCalledWith
などの Matcher を試す。
Top comments (0)