테스트 코드? Jest 만 설치해서 바로 사용하면 되는거 아니였나..?
UI 테스트와 테스트코드에도 타입스크립트를 사용하기 위해서는 추가적인 설정이 필요했다.
1. 타입 스크립트 적용을 위한 설정 (링크)
- 테스트 코드 내에서 타입스크립트를 사용하기 위해선 세가지 방법( babel, ts-jest, @jest/globals ) 중 하나를 선택해야한다.
babel
장: 실제 프로젝트 환경과 동일, 타입스크립트 관련해서는 추가적인 설정 파일이 필요하지 않음
단: esm 관련 추가적인 설정이 필요함
ts-jest
장: 환경 설정 편함, esm 관련 옵션 존재
단: 추가 설정 필요, 실제 프로젝트 환경과 다를 수 있음
@jest/globals
장: 환경 설정 편함
단: 매번 import 해서 사용해야함
최종적으로 babel 을 사용한 방법을 선택했다.
우리 프로젝트도 babel 을 사용하고 있으니 추가적인 설정 없이 프로젝트의 설정을 따라가야된다고 판단하여 babel 을 사용하게 되었다.
// babel.config.js
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-typescript',
],
};
// jest.config.js
transform: {
'\\.[jt]sx?$': ["babel-jest", { rootMode: 'upward' }],
}, --> 최상단의 babel 설정을 따라가겠다는 의미
babel 로 ts-> js 로 트랜스파일링을 진행하게끔 하였고
eslint-plugin-jest-dom, eslint-plugin-testing-library 를 사용하여 테스트코드 맞춤 린트를 사용할 수 있게끔 세팅했다.
@types/jest 를 설치하여 매번 import 하지 않아도 타입체킹이 되게 했다.
2. UI 테스트를 위한 설정
설치한 플러그인
- @testing-library/jest-dom, @testing-library/react, @testing-library/user-event, @testing-library/react-hooks
테스트 유틸 함수
- 전역에서 사용하는 컨텍스트들을 테스트코드 내에서도 동일하게 사용하게끔 환경 설정이 필요했다.
createWrapper
- customRender 와 customRenderHook의 중복되는 부분을 공용화한 함수
const createWrapper = ({
storeOptions,
historyOptions,
wrapper: Wrapper, // 지역 컨텍스트
}) => {
const { preloadedState } = storeOptions || {};
const store = configure(preloadedState); // redux 세팅
const history = createMemoryHistory(historyOptions); // react-router 세팅
if (Wrapper) {
const WrapperWithProps = ({ children, ...rest }: wrapperPropsType<IState, TAppAction>) => (
<AllTheProviders store={store} history={history} {...rest}>
{Wrapper(children)}
</AllTheProviders>
);
return { wrapper: WrapperWithProps, store, history };
}
const WrapperWithProps = (props) => (
<AllTheProviders store={store} history={history} {...props} />
);
return { wrapper: WrapperWithProps, store, history };
};
AllTheProviders
- UI 테스트 중 redux store, react Router 등의 값을 사용하기 위한 래퍼 컴포넌트
CustomRender
- AllTheProvider 및 store history 를 테스트 파일에서 사용하기위해 만든 함수 (렌더용)
- createWrapper 함수를 한 번 더 래핑하여 만들었다.
CustomRenderHook
- AllTheProvider 및 store history 를 테스트 파일에서 사용하기위해 만든 함수 (hook 용)
- createWrapper 함수를 한 번 더 래핑하여 만들었다.
3. 리덕스, 리덕스 사가 테스트를 위한 설정
testWithApiSaga
- apiSaga(회사의 saga 유틸) 전체 플로우와 함께 단순 테스트를 하고 싶은 경우 사용
4. 테스트 프로세스
개발 중일 때
- yarn test:watch 를 통해 수정한 파일에 대해서만 테스트
PR 올리거나 변경사항이 있을 때
- github workflow 를 통해 모든 테스트 실행 -> 실패/성공에 따른 결과는 코멘트에 표시
5. 트러블 슈팅
모노레포 전환과 디자인시스템 추가로 인한 문제
- 디자인 시스템의 path 가 실제 path 와 다르게 사용되었기 때문에 디자인 시스템을 사용중인 모든 테스트에 에러가 발생
> moduleNameMapper 를 사용하여 path 를 올바르게 잡아주었다.
moduleNameMapper: {
"^@wingeat/wis/(.*)$": "<rootDir>/packages/wingeat-wis/build/$1",
},
테스트 관련 라이브러리들간 버전 호환성
- 테스트 환경 구성 시점에 jest 는 29.3x 버전이였는데 types/jest 는 29.2x 가 최신이여서 맞춰서 설치를 했다.
코멘트 노이징
- 깃헙 액션으로 테스트 결과를 코멘트로 달게끔 해놓았는데 테스트를 실행할 때마다 코멘트가 생성되었기 때문에 노이지 하다는 의견을 들었다.
> 레이블을 추가하는 것으로 수정하였다.
Esm 모듈
- hackle 과 같은 esm 모듈을 읽지 못하는 에러가 발생
const esModules = ['@hackler/javascript-sdk'].join('|')
/** esModules 를 제외한 모든 node_modules 를 transform 할 때 무시 */
transformIgnorePatterns: [`<rootDir>/node_modules/(?!${esModules})`],
'공부 > React' 카테고리의 다른 글
Context 와 렌더링 이슈 (0) | 2023.08.24 |
---|