📌
EnzymeとReact Testing Libraryの違いを調べてみた
この記事は何?
- 過去に少しだけEnzymeを触ったことがあり、最近Reactを触るようになったため、公式から推奨されているテストライブラリについて調べた
Enzymeとは?
- Airbnb によって開発された
- React v16 までしかサポートしていない
- コンポーネントの内部構造や状態にフォーカスしており、コンポーネントのメソッドや状態を直接テストすることが可能
- コンポーネント内のメソッドを単体でテストすることができる
- Vue.jsのテストライブラリ(Vue Test Utils)に近い
React Testing Library
- Kent C. Dodds(Testing Trophyの考案者)によって開発された
- ユーザー視点でテストすることを重視しており、コンポーネントを操作して表示される内容をテストする
- E2Eに近いイメージ
- コンポーネント内にアクセスすることができない
コードで差を見てみる
※EnzymeとReact Testing Libraryを同時に使うため、React v16を使っています。
import React, { Component } from "react"
import { render, screen } from "@testing-library/react"
import { userEvent } from "@testing-library/user-event"
import "@testing-library/jest-dom"
import Enzyme, { shallow } from "enzyme"
import Adapter from "enzyme-adapter-react-16"
class Button extends Component {
constructor(props) {
super(props)
this.state = {
count: 0
}
}
handleClick = () => {
this.setState({ count: this.state.count + 1 })
}
render() {
return (
<div>
<button onClick={this.handleClick}>click</button>
<p>{ this.state.count }回クリックされました</p>
</div>
)
}
}
Enzyme.configure({ adapter: new Adapter() })
describe('Enzymeを使った場合のテスト', () => {
test('ボタンが押下されるとカウントが増えること', () => {
const wrapper = shallow(<Button />)
// Enzymeの場合 CSSセレクタ等に依存する
expect(wrapper.find('p').text()).toBe('0回クリックされました')
wrapper.find('button').simulate('click')
expect(wrapper.find('p').text()).toBe('1回クリックされました')
})
test('コンポーネントのインスタンスにアクセスできることの確認', () => {
const wrapper = shallow(<Button />)
expect(wrapper.find('p').text()).toBe('0回クリックされました')
wrapper.instance().handleClick()
expect(wrapper.find('p').text()).toBe('1回クリックされました')
})
})
describe('React Testing Libraryを使った場合のテスト', () => {
test('ボタンが押下されるとカウントが増えること', async () => {
render(<Button />)
// React Testing Libraryの場合 ユーザー視点でテストできる
expect(screen.getByText('0回クリックされました')).toBeInTheDocument()
await userEvent.click(screen.getByText('click'))
expect(screen.getByText('1回クリックされました')).toBeInTheDocument()
})
test.skip('コンポーネントのインスタンスにアクセスできない')
})
感想
- CSSセレクタ等に依存しないテストコードを書けるのは嬉しい
- CSSセレクタに依存すると、classの付け替え等簡単な変更でテストが落ちるようになる
- テスタブルなコードになっていないとReact Testing Libraryは使いにくそうに感じた
- テストファーストやTDDで解決できそう
- 先にユーザー視点でCSSセレクタ等に依存しないテストコードを書くことで、自然にテスタブルなプロダクションコードが書けそう
Discussion