프론트엔드 자동화 테스트 영역에서 사용자 상호작용을 효과적으로 시뮬레이션하는 것은 매우 중요합니다. user-event 라이브러리는 실제 사용자의 웹페이지 상호작용을 가까운 형태로 재현할 수 있어, 복잡한 폼 작업과 파일 업로드 시나리오를 테스트하는 데 유용한 도구를 제공합니다.
user-event로 폼 상호작용을 처리하는 이유
기존 이벤트 시뮬레이션 도구들과 비교할 때, user-event는 다음과 같은 핵심 장점을 제공합니다:
- 완전한 사용자 행동 시뮬레이션: 단순 이벤트 발생을 넘어 실제 사용자의 전체 상호작용 과정을 재현합니다
- 스마트 폼 처리: 폼 요소 간의 연관 관계와 검증 로직을 자동으로 처리합니다
- 파일 업로드 내장 지원: 직관적인 파일 업로드 시뮬레이션 API를 제공합니다
- 키보드 내비게이션: 복잡한 키보드 작업과 단축키 조합을 지원합니다
복잡한 폼 상호작용 구현 기법
1. 선택 요소의 정확한 제어
user-event는 다양한 폼 요소를 조작하기 위한 풍부한 API를 제공합니다. 드롭다운 선택의 경우, selectOptions 메서드를 활용하여 선택 동작을精确하게 제어할 수 있습니다:
// 단일 옵션 선택
await user.selectOptions(categorySelect, 'electronics')
// 복수 옵션 선택
await user.selectOptions(multiSelect, ['option-a', 'option-c'])
이 구현은 src/utility/selectOptions.ts 파일에서 확인할 수 있으며, 다양한 유형의 선택 요소 처리 로직이 포함되어 있습니다.
2. 폼 제출의 스마트 처리
user-event는 실제 사용자의 폼 제출 행동을 시뮬레이션할 수 있습니다. 제출 버튼 클릭과 Enter 키 제출 모두 지원합니다:
// 제출 버튼 클릭을 통한 폼 전송
await user.click(submitButton)
// Enter 키를 통한 폼 전송
await user.keyboard('{enter}')
tests/event/behavior/keypress.ts 테스트 파일에서 다양한 폼 제출 시나리오의 테스트 케이스를 확인하실 수 있습니다.
3. 폼 검증 및 오류 메시지 처리
검증 로직이 포함된 폼을 처리할 때는 user-event와 단언 라이브러리를 결합하여 오류 메시지를 검증할 수 있습니다:
// 빈 폼 제출 시도
await user.click(submitButton)
// 오류 메시지 표시 검증
expect(screen.getByText('필수 항목을 입력해주세요')).toBeInTheDocument()
파일 업로드 전체 구현 가이드
1. 기본 파일 업로드
upload 메서드를 사용하면 파일 업로드 작업을 쉽게 시뮬레이션할 수 있습니다:
// 테스트용 파일 생성
const testFile = new File(['파일 내용'], 'sample.pdf', { type: 'application/pdf' })
// 파일 업로드 실행
await user.upload(inputElement, testFile)
2. 다중 파일 업로드
user-event는 한 번의 동작으로 여러 파일을 업로드할 수 있습니다:
// 여러 테스트 파일 생성
const documents = [
new File(['문서 내용'], 'doc1.pdf'),
new File(['문서 내용'], 'doc2.pdf')
]
// 다중 파일 업로드
await user.upload(inputElement, documents)
3. 레이블을 통한 간접 파일 업로드
label 요소를 间접적으로 통해 트리거되는 파일 업로드도 정확히 처리됩니다:
// 레이블 클릭을 통한 파일 업로드
await user.upload(labelElement, uploadFile)
src/utility/upload.ts 파일에서 다양한 파일 업로드 시나리오의 구현 로직을 확인하실 수 있습니다.
특수 상황 처리를 위한 고급 기법
1. 비활성화된 요소의 상호작용
비활성화된 요소와 상호작용을 시도하면 user-event는 명확한 오류를 발생시킵니다:
// 비활성화된 버튼 클릭 시 오류 발생 예상
await expect(user.click(inactiveButton)).rejects.toThrow()
2. 포인터 이벤트 처리
복잡한 포인터 이벤트, Seperti 호버와 드래그 앤 드롭을 처리할 수 있습니다:
// 요소 위로 마우스 이동
await user.hover(cardElement)
// 드래그 앤 드롭 동작
await user.dragAndDrop(sourceItem, targetItem)
3. 키보드 단축키 시뮬레이션
키보드 단축키가 필요한 시나리오에서는 keyboard 메서드를 활용합니다:
// Ctrl+S 저장 단축키 시뮬레이션
await user.keyboard('[ControlLeft>]s')