UI 테스트
이 섹션에서는 개발자들이 UI와 관련된 코드베이스를 어떻게 테스트할지 설명합니다.
테스트 스택
모든 UI 테스트는 반드시 다음을 사용하여 수행해야 합니다 Jest 를 주요 테스트 프레임워크로 사용하고 redux-saga-test-plan 을 saga 테스트 도구로 사용하고 react testing library 를 UI 컴포넌트 테스트 도구로 사용해야 합니다. 테스트 코드는 반드시 다음을 사용해 작성해야 합니다: TypeScript 를 사용하여 실행하고 ts-jest 를 사용해 타입 검사 지원을 가져야 합니다.
무엇을 테스트할지
UI 컴포넌트
사가
리듀서
셀렉터
액션 크리에이터
유틸리티 함수
사가 테스트
Sagas는 redux 액션을 처리하는 제너레이터를 만들어 부수 효과를 다루게 해줍니다. sagas의 주요 장점 중 하나는 테스트 가능성으로, sagas에서 널리 사용되는 effect들은 테스트하기 매우 쉽습니다.
이러한 핸들러는 반드시 다음을 사용해 테스트해야 합니다: redux-saga-test-plan그리고 테스트는 전체 실행을 검증해야 합니다. 즉, 모듈 전체의 핸들러(메인 핸들러 또는 saga)부터, 우리가 디스패치할 액션에 반응할 모든 핸들러의 실행까지 포함해야 합니다. 이 접근 방식은 saga 테스트를 만들고 유지하기 쉽게 해 주며, 가능한 한 전체 흐름을 최대한 거치게 하므로 테스트의 가치를 높여 줍니다.
핸들러의 테스트는 주로 다음을 포함한 effect와의 상호작용을 통해 수행되어야 합니다: put 입니다. 그 목적은 액션을 처리하고 새 액션을 만들어 내는 데 있기 때문입니다. 대부분의 테스트에는 반드시 다음이 포함될 것입니다: provide 호출은 effect를 모킹하는 데 사용되며, 하나 또는 여러 개의 put 호출을 통해 핸들러가 예상대로 액션을 디스패치하는지 확인하고, 그리고 단일 dispatch 뒤이어 run 호출로 전체 sagas를 완료까지 실행합니다.
테스트 중인 모듈 외부 리소스의 모킹은 redux-saga-test-plan providers를 사용해 수행해야 하며, redux-sagas가 제공하는 다양한 effect를 활용해야 합니다. call, apply 같은 effect나 그 밖의 것들은 함수가 테스트에서 호출될 때 쉽게 모킹할 수 있도록 가능하다면 언제나 사용해야 합니다. Jest를 사용해 모듈이나 함수를 모킹해서는 안 됩니다.
describe 안의 텍스트와 그 MUST는 다음 지침을 따라야 합니다:
saga 또는 메인 핸들러의 주요 describe는 반드시 다음으로 시작해야 합니다: when handling로 시작해야 하며, 이는 테스트 대상이 핸들러임을 나타냅니다. 다음 when handling 문구 뒤에는 처리할 액션(또는 액션의 의도)에 대한 설명을 반드시 작성해야 합니다. 예: 성공적인 가져오기를 알리는 액션을 처리할 때.
내부 describe는 실행 컨텍스트를 구분하며, 다음의 컨텍스트 설명 및 구성 섹션에서 설명한 것과 같은 규칙을 따릅니다.
그 its는 테스트에서 기대하는 바를 설명해야 하며, 다음으로 시작해야 합니다: should put 그리고 핸들러를 실행할 때 put되어야 하는 액션의 설명이 뒤따라야 합니다.
Sagas 예제
Sagas 테스트 예제
리듀서 테스트
리듀서는 state와 액션을 받아 새 state를 반환하는 함수입니다. 이 새 state에는 주어진 액션에 따라 발생하도록 프로그래밍된 변경이 포함될 수 있습니다.
필요하다면 테스트는 초기 state와 테스트할 액션의 다양한 매개변수를 달리해야 합니다. 액션이 주어진 초기 state의 어느 부분이든 수정할 수 있으므로, 검증은 반환된 전체 state에 대해 이루어져야 합니다.
액션을 리듀싱할 때는 테스트를 더 쉽게 유지보수할 수 있도록 액션 크리에이터를 사용하는 것이 좋습니다.
우리가 작성하는 방식을 표준화하기 위해 describe와 it는 다음과 같이:
메인 describe는 다음 문구를 사용해 어떤 액션이 리듀스될지 설명하는 것으로 시작해야 합니다: when reducing the action 뒤이어 액션에 대한 설명이 와야 합니다. 액션의 타입은 변경될 수 있으므로, 테스트 대상 액션을 설명할 때 액션 타입을 사용해서는 안 됩니다.
그 its는 반환된 state가 어떻게 변경되었는지 명확하게 설명해야 합니다. 예: 에러가 null로 바뀌고 fruits가 설정된 state를 반환해야 한다.
리듀서 예제
리듀서 테스트 예제
셀렉터 테스트
셀렉터는 state를 받아 해당 state의 일부 또는 변환된 일부를 반환하는 메서드입니다.
셀렉터에는 메모이즈된 셀렉터와 일반 셀렉터, 두 가지 유형이 있습니다. 일반 셀렉터는 다른 단위 테스트 함수처럼 테스트해야 하며, 메모이즈된 셀렉터는 다음을 사용해 테스트해야 합니다: resultFunc 또는 메모이즈된 state의 일부를 받아 원하는 값을 반환하는 함수.
설명와 its는 다음 섹션에서 설명한 대로 작성해야 합니다: 컨텍스트 설명 및 구성 섹션에서 설명한 것과 같은 규칙을 따릅니다.
셀렉터 예제
셀렉터 테스트 예제
액션 크리에이터 테스트
액션 크리에이터는 나중에 리듀서에서 처리될 액션을 만드는 일을 담당합니다. 액션 크리에이터는 보통 단순하지만, 우리가 기대하는 대로 동작하는지 확인하기 위해 테스트해야 합니다.
설명와 its는 다음 섹션에서 설명한 대로 작성해야 합니다: 컨텍스트 설명 및 구성 섹션에서 설명한 것과 같은 규칙을 따릅니다.
액션 크리에이터 예제
액션 크리에이터 테스트 예제
UI 컴포넌트 테스트
UI 컴포넌트를 테스트할 때는 다음을 사용합니다: React Testing Library. 우리는 enzyme 같은 다른 옵션 대신 이 라이브러리를 사용합니다. 사용자가 구현 자체가 아니라 컴포넌트와 어떻게 상호작용하는지를 고려해 컴포넌트를 테스트할 수 있게 해 주기 때문입니다. React 컴포넌트 인스턴스와 상호작용하는 대신, 렌더링된 방식대로 DOM 요소와 상호작용합니다.
무엇을 테스트할지
이 UI 컴포넌트 테스트의 목적은 컴포넌트의 동작과 사용자가 그것과 상호작용하는 방식을 테스트하는 것입니다. 많은 경우 어떤 속성을 얻고 일부 액션을 호출하기 위해 redux store에 연결된 컴포넌트가 있을 수 있습니다. 우리는 보통 이를 별도의 container 파일로 분리하여 store와 상호작용하게 합니다. 이러한 파일은 이런 종류의 테스트 범위 밖입니다. 우리는 컴포넌트가 서로 다른 prop 값으로 어떻게 동작하는지 테스트하며, 그 값의 출처(redux store, context, 부모 컴포넌트)는 중요하지 않고 최종 렌더링에 어떤 영향을 미치는지가 중요합니다.
렌더링
모든 테스트는 render 함수를 호출하는 것으로 시작해야 합니다. 그러면 매개변수로 전달한 컴포넌트뿐 아니라 모든 자식 컴포넌트도 렌더링됩니다. 테스트 설정(beforeEach)에서 이렇게 하는 것은 DOM 트리에 원치 않는 컴포넌트가 더 많이 생기게 하여 문제를 일으킬 수 있으므로 피해야 합니다. 결과는 다음 이름의 속성에 저장해야 합니다: screen. 이렇게 하면 구조 분해를 계속 바꿀 필요 없이 테스트에 필요한 모든 속성을 얻을 수 있습니다.
문서에 여러 테스트가 있고 컴포넌트에 여러 prop이 있다면, 파일 상단에 기본 prop을 설정하고 컴포넌트를 렌더링하는 함수를 만들 수 있습니다.
쿼리
쿼리는 Testing Library가 페이지에서 요소를 찾도록 제공하는 메서드입니다. 사용할 수 있는 다양한 쿼리 종류 가 있습니다. 요소에 접근할 때는 항상 모두에게 접근 가능 한 쿼리를 사용하도록 노력해야 합니다. 이것이 모든 사용자(시각/마우스 사용자와 보조 기술 사용자)의 경험을 반영하기 때문입니다.
그러한 쿼리는 다음과 같습니다: getByRole, getByLabelText, getByPlaceholderText, getByText, getByDisplayValue. 이 쿼리를 사용해 요소에 접근할 수 있다면, 그 컴포넌트가 접근 가능하지 않다는 뜻일 수 있습니다.
사용자 이벤트 테스트
컴포넌트 내부 함수에 접근할 수 없으므로, 해당 함수가 호출되도록 이끄는 사용자 행동을 모방해야 합니다. 이를 위해 다음을 사용합니다: userEvent 라이브러리.
디버깅
특정 시점의 테스트와 DOM의 현재 상태를 디버그하려면 다음을 사용할 수 있습니다: debug 는 render를 호출했을 때 반환되는 속성 중 하나인 함수입니다
UI 컴포넌트 테스트 전체 예제
디렉터리 구조
테스트는 반드시 실행할 파일이나 모듈과 같은 이름을 가지고, 확장자가 spec.ts 로 ts.
다음과 같은 파일 구조를 가져야 합니다:
마지막 업데이트