React Testing Library + Jest 도입기를 빙자한 반성문
팀프로젝트에 늦게나마 RTL 과 Jest 를 활용한 테스트를 추가한 이야기이다.
왜 이제와서 테스트코드를 썼나요? 👮🏻♂️
우테코 팀프로젝트 기간이 끝나면서, 그간 한 코드들을 정리해보는 시간을 가지게 되었다. 그러다가 양방향 무한스크롤 구현기를 정리했고, 다시 찾아보다가 상향 무한스크롤에 onWheel 이벤트만 적용되어 있어서 사용자가 직접 마우스나 키보드로 스크롤을 움직이면 상향 무한스크롤이 적용 안되는 것을 발견했다. 🤦🏻♀️ 해당 기능은 그래도 wheel, touch 이벤트 시 정상동작하기 때문에 급한사항은 아니라고 판단해서 천천히 고칠 예정이다.
하지만 이 사건을 계기로 사용자 행동에 대한 테스트코드를 착실히 작성해야 한다는 것을 깨달았다. 만약 내가 상향 무한스크롤에 대한 테스트코드를 작성해놓았다면, 애초에 구현 했을 때 이 문제점을 알고 구현하지 않았을까 하는 아쉬움이 남았다. 그래서 늦게라도 테스트코드를 추가하기로 마음먹었다.
왜 하필 컴포넌트 테스트인가요? 👮🏻♂️
일단 위의 경험으로 절실히 필요해보였던 것은,
해당 컴포넌트(페이지 역시 컴포넌트)가 어떤 사용자 액션이 있었을 때, 원하는대로 정상적으로 렌더링되느냐
를 판단하는 것이었다. 그래서 컴포넌트 테스트를 도입했다.
그러면 e2e 테스트가 더 적합한거아냐? 라고 생각 할 수 있지만, e2e 테스트를 하려면 어플리케이션 전체가 연결되어 있는 테스트를 작성해야하므로 리소스가 굉장히 많이 들어간다고 판단했다. 더구나 우리 서비스가 Slack OAuth 를 사용하므로, 이러한 부분도 처리하기 까다로웠다.
또한, 우리 서비스에서 급하게 필요하다고 생각한 것은 전체 사용자 플로우가 아니라 오로지 주요로직에 대한 테스트였다. 테스트코드를 작성하는 것도 비용이 들기 때문에 전체 사용자 플로우를 처리해야하는 e2e 테스트를 작성하는 것은 현재 처한 상황에 걸맞지 않다고 판단했다. 이렇게 하면 정말 중요한 단일 컴포넌트의 엣지 케이스를 놓치기 쉽다고 판단했다. 그래서 하나의 컴포넌트 단위로 나누어서 테스트를 할 수 있는 RTL 을 사용한 컴포넌트 테스트를 선택했다.
( 물론 아직 좋은 테스트코드는 완성하지 못했지만, 그래도 테스트코드를 작성한데에 의의를 둔다. 🥲)
테스트코드는 왜 필요할까요? 👮🏻♂️
함수 내부에서 처리되는 로직이 복잡 할 때 (엣지케이스가 많다고 판단 될 때)
테스트코드가 빛을 발하는 것 같다. 하나의 로직이 더 추가 되어도, 결과값이 같지 않을 수 있기 때문이다.
함수라고 표현했지만, 리액트 컴포넌트에도 동일하게 적용된다.
- 컴포넌트 내부의 렌더링 관련 로직이 복잡하거나
- 컴포넌트 내부의 상태가 많거나 서로 결합도가 높을 때
테스트코드를 꼭 작성해야한다고 생각한다.
나만의 테스트코드 작성 기준 👮🏻♂️
그렇담 나는 어떤 기준으로 테스트코드를 작성할까? 사실 어떤 기준으로 테스트를 작성하지 않는가가 더 명확한 것 같다. 예전에 미션하면서 머릿속에 많이 정리해뒀었는데..아래와 같다.
- 단순히 1+1 = 2 와 같은 로직은 테스트 하지 않는다. 매개변수를 받아서 반환해줄 때 까지, 중간에
단순 계산, 타입 변환 등등..외의 더 복잡한 로직
이 있을 경우. 즉 반환값을 사용처에서 쉽게 예측할 수 없을 경우에 테스트를 작성한다. - 외부 라이브러리를 사용하기만 하는 로직은 테스트를 작성하지 않는다. 예를들면 아래와 같다.
const Test = () => {
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
fetch('api').then(() => {
setIsLoading(true);
});
}, []);
// ... 생략
};
위와 같은 코드에서 isLoading
이 제대로 변하는걸 굳이 테스트해줘야할까? (나는 예전에 했었다..)
이미 리액트라는 라이브러리에서 대신 처리해주고 있는 로직 (setState) 를 굳이 테스트해줘야 할 필요는 없다.
자! 앞으로는 테스트코드를 부지런히 작성합시다. 👮🏻♂️
프론트엔드 개발자에게 테스트코드란 뭘까..자칫하면 ‘잉? 이게 과연 필요할까?‘라는 자기합리화에 묻혀서 테스트코드의 존재가치 자체를 부정하게 된다.
왜일까? 어차피 사용자에게 보여질 것을 만들기 때문이고, 만드는 도중 계속 개발자들이 눈으로 결과물을 직접 보기 때문이 아닐까.
하지만..사람이 직접 테스트하기에는 놓치기 쉬운 것들이 너무나 많고, 테스트의 결과물/증거를 문서화하거나 기록 할 수 없다는 것이 문제점 인 것 같다.
내가 로컬에서 돌려보니까 됐어!
와 같은 말을 하는 사람이 되지 않도록..테스트코드의 작성을 생활화 하자.
테스트코드가 처음부터 완벽해질 필요는 없다. 위에서도 언급했듯, 테스트코드를 작성하는데에는 그만큼 많은 비용이 들기 때문이다. 그래도 테스트코드를 작성해두는 것 만으로도 의의가 있고 좋은 효과를 얻을 수 있다고 생각한다.
이 곳 에 가면 Kent C Dodds 님께서 테스트를 왜 작성해야하는지 뼈때리는 말씀을 많이 하신다. 우리 모두 테스트코드의 작성을 생활화 합시다!!
끗!
p.s RTL+Jest+TypeScript 환경설정하는데 정말 열심히 도와주신 익명의 크루께 영광을 돌립니다 정말 감사합니다..💙