테스팅 코드 작성 이점이 아닌 것 > 작성할 코드가 줄어 개발시간이 짧아짐
테스팅 분류 용어에 대한 설명 중 틀린 것 > 유저가 어떤 시나리올를 가지고 그 시나리오 대로 테스트 하는 경우 integration testing 사용함
react 테스팅
코드 테스트가 필요한 경우
코드 작성 후 원하는 대로 동작하는 지 알기 위함
코드에 버그가 았으면 어떤 상황에서 버그가 발생하는 지 알기 위함
코드 리펙토링 후 원하는 대로 동작하는 지 알기 위함
리액트 앱의 컴포넌트가 늘수록 컴포넌트끼리 영향 미치는 경우 많아짐
특정 코드 수정 후 어떤 컴포넌트에서 에러 발생 가능
테스팅 코드 작성 이점
미연의 에러 방지
tdd(test driven development) 등 방법론 적용해 생산성 향상
테스트 증가로 테스트 코드가 구현 코드에 대한 문서화가 됨
테스트가 용이하게 코드 작성 해 코드 품질과 신뢰성 높임
테스터블한 코드 작성하기
코드가 영향을 미치는 범위는 최대한 줄이기 + 사이드 이펙트 줄임(외부변경을 일으키는 코드)
하나의 함수가 너무 많은 일을 하지 않도록 함
기능을 작게 분리함
주요 테스팅 용어
mocking - 특정 동작 흉내냄 > 실제 api호출이 아닌 가짜 payoad를 반환
stubbing - 더미 채워넣음 > chilld 컴포넌트 렌더링 하지 않고 그 자리에 <div> 등을 채워넣
setup - 테스트 하기 위한 환경 만듦 > mock data, mock function 등을 준비함
expectation - 원하는 테스트 결과를 만들기 위한 코드 작성
assertion - 정말 원하는 결과가 나왔는지 검증
화이트박스 테스팅 - 컴포넌트 구조 알고있는것을 가정 후 테스트 코드 작성
블랙박스 테스팅 - 컴포넌트 구조 모른 채 테스트 코드 작성
테스팅 범위에 따른 분류
- unit 테스팅
다른 부분과 분리된 작은 코드 만들고 그것을 테스트함( 작은 코드는 funciton, module, class 등)
각 부분이 원하는 대로 동작함을 보장하기 위함
테스트는 서로 분리되어야 함(특정 컴포넌트가 데이터에 따라 잘 렌더링 되는지를 테스트하는 경우)
- integration 테스팅
앱의 특정 부분이 동작하는 지 테스트(여러 컴포넌트가 한까번에 동작 / 어떤 페이지의 한 부분이 잘 동작하는 지 테스트)
+ react-router, redux 등 특정 컴포넌트와 함께 잘 동작하는 지 테스트
- end-to-end(e2e) 테스팅
유저가 어떤 시나리오를 가지고 그 시나리오의 end-to-end로 잘 동작하는 지 테스트
필요한 경우 웹서버, 데이터베이스 실행함
범위가 너무 넓어 에러 발생 시 특정 기능이 동작하지 않는건 알 수 있음 + 정확히 어떤 부분에 문제가 생겼는지 알기 힘듦
(회원가입 후 로그인해 유저정보페이지 볼 수 있는 지 테스트 하는 경우)
jest
페북에서 오픈소스화한 테스팅 프레임워크
assertion함수, test runner, mock 라이브러리 등 제공
create-react-app에서 기본적으로 사용
사용성이 좋고 가장 인기있는 프로젝트
핵심기능
- assertion matchers
jest는 풍부한 matcher제공해 여러 상황에서 match 체크함
expert()는 expectation object 리턴 > object의 메서드 이용해 여러 매칭 상황 assert함
- async assertion
비동기 상황 테스트 처리할 수 있는 여러 방법 제공
callback, promise, async/await 모두 활용 가능
- mock functions
mock function 만듦
모듈 전체 mocking함
라이브러리 전체 mocking함
- ifecycle functions
각 테스트 시작과 끝, 전체 테스트 시작과 끝에 원하는 작업 가능
beforeEach, afterEach, beforeAll, afterAll 함수 활용
describe 블론 안에 사용 시 별도의 스코프 가짐
- grouping
describe함수 이용해 여러 test()함수를 논리적으로 나눔
describe함수 안에 describe함수 중첩 가능
- snapshot testing
특정 함수, 모듈, 컴포넌트 등의 결과를 serializable한 형태의 snapshot 으로 저장
> 변경 발생 시 이전 snapshot과 새 snapshot 비교해 변경 발생 여부 추측함
jest 주요 기능으로 코드 변경이 컴포넌트 렌더링 결과에 영향이 미치는지 파악에 적합
jset함수 실행 순서
beforeAll, beforeEach,afterEach,afterAll순서로 lifecycle함수 실행
describe 블록 안 befor, after함수는 해당 블록 범위 안에서 실행됨
descibe함수는 모든 test()함수 이전에 실행됨 > test()함수들은 순차적으로 한꺼번에 실행됨
assertion matchers활용
toBe() - 객체 내용 비교
toEqual() - 객체 자체 비
toContain() toMatch() toThrow()
async assertion활용
callback패턴 경우 test()함수가 제공하는 done()함수 활용해 콜백 끝나고 done()호출함 / 에러 발생 시 done()인자로 넘김
promise패턴 경우 async/await활용하거나 promise리턴
mock functions활용
jest.fn()활용해 mock function 객체 만듦
mockReturnValueOnce() 등으로 리턴하는 값을 임의로 조작함 > 여러번 호출 시 순서대로 세팅된 값 반환
mockResolvedValue()로 promise가 resolve하는 값 조작함
jest.mock()로 특정 모듈 mocking함
mock functions - assertion
toHaveBeenCalled - 이 함수가 호출되었는지 검증
toHaveBeenCalledWith(arg1,arg2...) - 이 함수가 특정 인자와 함께 호출되었는지 검증
toHaveBeenLastCalledWith(arg1,arg2...) - 마지막으로 특정 인자와 함께 호출되었는지 검증
lifecycle function
beforeEach, afterEach, beforeAll, afterAll
호출 순서
beforeAll
before > test1 > after(한 묶음)
before > test2 > after
>>...
afterAll
grouping
descibe() test()
snapshot testing
toMatchSnapshot()호출 시
기존 스냅샷이 없을 경우 - .snap파일 만듦
기존 스냅샷 있을 경우 - 새로운 스냅샷과 비교해 변경사항 있을 시 테스트 실패
toMatchInlineSnapshot() 호출 시 별도의 파일 만들지 않음(어떻게 스냅샷이 쓰였는지 한 파일 안에서 알 수 있음)
react-testing-library
테스트가 sw사용되는 모습을 닮을수록 테스트 신뢰도 상승
react컴포넌트의 특정 메서드나 상태 테스트x > 실제 유저가 사용하는 방식대로 테스트
유저가 페이지에서 어떤 dom요소에 접근하는 방법 흉내 > 내부구현 바뀌어도 테스트 께지지않음
react 컴포넌트가 렌더링한 결과에 대한 접근만 가능
쿼리는 내부 상태나 내부 메서드에 접근할 수 없게 설계됨
get 쿼리
getBy - 원하는 요소 찾아 반환 / 찾지 못할 경우나 여러 요소를 찾을 경우 에러 던짐
getAllBy - 여러 요소 찾아 배열로 반환 / 원하는 요소 못찾을 경우 에러 던짐
원소가 반드시 페이지에 존재해야만 하는 경우 활용
find쿼리
findBy - 원하는 요소가 없더라도 비동기적으로 기다림
findAllBy - 여러 원소 검색해 배열로 반환 / 정해진 timeout동안 못찾을 시 에러 던짐
여러 원소를 찾거나 정해진 timeout동안 못찾을 시 에러 던짐
promiise리턴하며 실패시 reject / 성공시 resolve
어떤 유저의 동작 후 등장하는 원소 등을 테스트 시 활용
query 쿼리
queryBy - getBy와 비슷하게 원소 찾아 반환 / 못찾을 경우 null 반환 > 여러 원소를 찾으면 에러 던짐
queryAllBy - getAllBy와 비슷하게 여러개의 원소를 찾아 배열로 반환 / 하나도 못찾으면 에러 대신 빈배열 반환
특정 요소 찾을 수 없음 - assertion 기준으로 둘 때 활용됨
container 쿼리
컴포넌트 렌더한 결과를 감싸는 원소
queryselector(), querySelectorAll() 이용해 selector 문법으로 원소 선택 가능
jset-dom
react-testing-library는 jest 확장해 좀 더 쓰기 편한 assertion제공
toBeInTheDocument(), toHaveValue(), toBeDisabled(), toBeVisible() 등 dom 테스팅에 유용한 assertion 메서드 제공
쿼리 우선순위
유저가 페이지를 이동하는 방식에 가까운 쿼리일수록 우선순위 높음
접근성 높은 html작성할수록 테스트 용이한 코드
byRole
ex) getByRole, findByRole, queryByRole 등 쿼리 뒤에 role 붙이면 가장 높은 우선순위 가짐
accessibility tree에 있는 요소들을 기준으로 원소를 찾음
유저가 웹페이지 사용하는 방식과 가장 닮은 쿼리
동일한 role을 가진 경우 accessible name을 이용해 원소 구별
자주 사용되는 role - button, checkbox, listitem, heading, img, form. textbox, link
자주 사용되는 accesible name - button - 텍스트 / label- 텍스트 / a - 텍스트 / img - alt 텍스트
> 텍스트는 <button>submit</button> 일 때 submit
text
유저가 볼 수 있는 text값을 기준으로 쿼리 찾음 >> 페이지에 보이는 텍스트
byLabelText - label과 연관된 원소 찾음
byPlaceholderText - placeholder와 연관도니 원소 찾음
byText - 주어진 text와 연관된 원소 찾음
byDispayValue - input, textarea, select 등의 값을 기준으로 원소 찾음
semantic queries
유저에게 보이지 않지만 접근성 스펙에 적합한 alt, title 등을 이용해 원소 검색
byAltText - img, area, input 등의 alt 속성으로 원소 검색
byTitle - title속성으로 원소 검색
test id
data-testid 속성으로 원하는 원소에 지정하고 쿼리를 이용해 찾음
유저가 해당 속성을 기바으로 화면의 요소를 찾는게 아님 > 우선순위 낮음
다른 쿼리로 테스트 작성 불가 > 해당 쿼리를 백도어로 활용
유저이벤트
내장 이벤트 함수인 fireEvent, createEvent를 좀 더 직권적이고 범용적으로 사용할 수 있도록 만든 라이브러리
click, type, keyboard, upload, hover, tab 등 유저가 페이지를 사용하며 만드는 이벤트를 메서드로 제공
userEvent.type() - 타이핑 > 값 입력 가능
#엘리스트랙 #엘리스트랙후기 #리액트네이티브강좌 #온라인코딩부트캠프 #온라인코딩학원 #프론트엔드학원 #개발자국비지원 #개발자부트캠프 #국비지원부트캠프 #프론트엔드국비지원 #React #Styledcomponent #React Router Dom #Redux #Typescript #Javascript
'엘리스_이론' 카테고리의 다른 글
23.12.06(스타일 컴포넌트1) (1) | 2023.12.08 |
---|---|
23.12.04(ssr, 배포) (0) | 2023.12.04 |
23.11.29(redux) (0) | 2023.11.29 |
23.11.27(상태관리) (1) | 2023.11.27 |
23.11.24 (react 비동기통신) (0) | 2023.11.24 |