반응형
TLDR:
- mocking을 이용하여 software가 어떻게 사용되는지(how)를 명시적으로 테스트 할 수 있습니다. > jest.fn
- 테스트 케이스 작성 시에는 소프트웨어가 사용되는 how에 집중하는게 좋습니다.
- faker 라이브러리를 사용하여 매번 가짜 데이터를 만들 수 있습니다.
- 테스트 객체를 쉽게 만들기 위해 오브젝트 팩터리 함수를 사용합니다.
사용자는 Form과 상호 작용하는 데 많은 시간을 할애하며 Form은 응용 프로그램에서 가장 중요한 부분입니다
(예: 전자 상거래 앱의 "체크아웃" Form 또는 대부분의 앱의 "로그인" Form).
사용자가 Form에서 입력을 찾고, 정보를 입력하고, Form을 제출할 때 제출된 데이터가 올바른지 확인할 수 있는지를 검증합니다.
로그인 폼 검증
테스트할 컴포넌트는 다음과 같습니다.
function Login({onSubmit}) {
function handleSubmit(event) {
event.preventDefault()
const {username, password} = event.target.elements
onSubmit({
username: username.value,
password: password.value,
})
}
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="username-field">Username</label>
<input id="username-field" name="username" type="text" />
</div>
<div>
<label htmlFor="password-field">Password</label>
<input id="password-field" name="password" type="password" />
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
)
}
export default Login
브라우저의 접근성 탭과, 테스팅 플라이그라운드를 활용하여 더 나은 품질의 테스트를 작성해 봅시다.
input type="password"에는 보안을 위해 암시적 Role이 없습니다.
통일성을 위해 username도 동일한 방법으로 쿼리합시다.
test('submitting the form calls onSubmit with username and password', () => {
let submittedData
const handleSubmit = data => (submittedData = data)
render(<Login onSubmit={handleSubmit} />)
const username = 'chucknorris'
const password = 'i need no password'
userEvent.type(screen.getByLabelText(/username/i), username)
userEvent.type(screen.getByLabelText(/password/i), password)
userEvent.click(screen.getByRole('button', {name: /submit/i}))
expect(submittedData).toEqual({
username,
password,
})
})
jest.fn()이용한 mocking
mocking을 이용하여 software가 어떻게 사용되는지(how)를 명시적으로 테스트 할 수 있습니다.
객체지향 설계, API 설계 시 how를 캡슐화 하는것은 중요하지만,
테스트 케이스 작성 시에는 소프트웨어가 사용되는 how에 집중하는게 좋습니다.
toHaveBeenCalledWith로 해당 파라미터로 호출되었는지,
toHaveBeenCalledTimes으로 단 한번만 호출되었는지 검증합니다.
test('submitting the form calls onSubmit with username and password', () => {
const handleSubmit = jest.fn()
render(<Login onSubmit={handleSubmit} />)
const username = 'chucknorris'
const password = 'i need no password'
userEvent.type(screen.getByLabelText(/username/i), username)
userEvent.type(screen.getByLabelText(/password/i), password)
userEvent.click(screen.getByRole('button', {name: /submit/i}))
expect(handleSubmit).toHaveBeenCalledWith({
username,
password,
})
expect(handleSubmit).toHaveBeenCalledTimes(1)
})
테스트 데이터 만들기
테스트에 사용되는 가짜 데이터가 어떤 값인지는 의미가 없습니다.
const username = getRandomUsername()
const password = getRandomPassword()
faker 라이브러리를 사용하여 매번 가짜 데이터를 만들 수 있습니다.
const {username, password} = buildLoginForm()
import * as React from 'react'
import {render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import faker from 'faker'
import Login from '../../components/login'
function buildLoginForm() {
return {
username: faker.internet.userName(),
password: faker.internet.password(),
}
}
test('submitting the form calls onSubmit with username and password', () => {
const handleSubmit = jest.fn()
render(<Login onSubmit={handleSubmit} />)
const {username, password} = buildLoginForm()
userEvent.type(screen.getByLabelText(/username/i), username)
userEvent.type(screen.getByLabelText(/password/i), password)
userEvent.click(screen.getByRole('button', {name: /submit/i}))
expect(handleSubmit).toHaveBeenCalledWith({
username,
password,
})
expect(handleSubmit).toHaveBeenCalledTimes(1)
})
오버라이딩 허용하기
때때로 특정 값이 중요한 역할을 해야할 때가 있습니다. (ex root 사용자)
아래와 같이 오브젝트 팩토리를 사용합니다.
function buildLoginForm(overrides) {
return {
username: faker.internet.userName(),
password: faker.internet.password(),
...overrides,
}
}
테스트 데이터 봇
오브젝트 팩토리 함수를 만드는 것이 복잡할 수 있습니다.
위의 오버라이딩 기능을 제공하면서, 가짜데이터를 만드는 유틸리티 기능을 동시에 제공하는 라이브러리 입니다.
주의! : 최신 2.0.0 버전은 faker 기능을 걷어낸 것 같습니다. 1.4.0 버전을 사용합니다.
@jackfranklin/test-data-bot - npm (npmjs.com)
import {build, fake} from '@jackfranklin/test-data-bot'
const buildLoginForm = build({
fields: {
username: fake(f => f.internet.userName()),
password: fake(f => f.internet.password()),
},
})
정리
- 폼에서는 입력 데이터 검증이 중요하다.
- 입력 데이터를 의미있게 생성 및 표현하는 것이 중요하다.
- submit시 액션 테스트도 중요하다.
반응형
'FrontEnd' 카테고리의 다른 글
React-Hook-Forms로 재사용 가능한 폼 만들기 (0) | 2022.06.28 |
---|---|
리액트 라우터 v6를 이용해 쉽게 모달 만들기 (0) | 2022.06.27 |
리액트 테스트 : implementation details을 피하기 (0) | 2022.06.26 |
리액트 테스트 : React Testing Library로 Counter 테스트하기 (0) | 2022.06.26 |
리액트 테스트 : 라이브러리 없이 Counter 테스트하기 (0) | 2022.06.26 |