본문 바로가기

FrontEnd+

프론트엔드 테스트 고민 일지

 

이 글은 내가 생각하는 정답이나 결론이 아닌 (장바구니 미션을 진행하면서) 프론트엔드 테스트 입문자로서 테스트 관련해서 고민했던 내용을 메모한 글이다.

굳이 테스트 작성하지 않아도 앱은 잘 돌아가는 것처럼 느껴진다. 타이트한 일정 속에서 '테스트를 꼭 작성해야 하나?' 라는 마음이 안 들었다면 거짓말이다. 테스트 코드는 왜 작성해야 할까?

 

테스트틀 작성해야 하는 이유

테스트 코드는 '보험'이다.

코드는 mutable 하다. 변경의 이유가 기능 추가/변경/삭제이든, 리팩토링이든, 항상 변경의 여지가 언제나 있다. 언제 얼마나 바뀔지 모른다. 그리고 이러한 변경 새로운 버그 발생의 가능성을 낳는다. 명확한 코드를 작성했다고 생각해도 그 안에 조용히 버그가 숨어있을 수 있다. 테스트 코드가 없다면, 이 버그는 시한폭탄을 품은 채 조용히 배포 코드까지 잠입하게 된다.

테스트 코드 작성은 코드의 잦은 변경에 따라 발생할 수 있는 버그를 예방해주는 대비책이다. 그런 점에서 테스트는 일종의 '보험'이라고 할 수 있다. 일어나지 않은 일이지만 리스크를 줄이기 위해 건강보험을 들듯, 언제 발생할지 모르는 버그 발생의 리스크를 줄이기 위해 테스트 코드를 작성한다. 기왕 보험을 든다면 종합보험으로, 그것도 보장 범위를 넓으면서도 중요한 종목이 쏙쏙 들어가 있는 알짜 보험을 찾는 것과 같이, 테스트 코드도 테스트 커버리지가 충분하도록 신경 쓴다. 테스트 코드를 작성하면 보험을 든 것처럼 심적 안정감도 얻을 수 있다. 

개발자는 코드를 작성함으로써 사용자에게 새로운 경험과 가치를 선사할 수 있다. 버그는 사용자에게 불편함과 실망감을 안겨주고, 사용자가 앱을 떠나게 한다. 버그 발생 가능성을 줄여준다는 점에서, 테스트 코드를 작성하는 것은 좋은 사용자 경험을 이끌어내는 데도 직접적으로 기여하는 방법이 아닐까?

TDD를 곁들이면 금상첨화

TDD(Test-Driven Development)란 테스트를 먼저 작성하고 기능을 구현하는 방식이다. 이 방식을 따르면 테스트를 작성하는 시점에서 구현할 기능을 좀 더 분석적으로 접근할 수 있다. 한 가지 테스트 코드를 작성한 후에, 이 테스트를 통과할 수 있는 한 가지 기능을 작성하는 식으로 개발을 진행하면, 각 기능에 대해 더 밀도 있게 집중해서 개발할 수도 있다.

기능 구현에 해야 할 고민을 이미 테스트 코드 작성 단계에서 거쳤기 때문에 기능 구현에 드는 시간이 단축된다. 테스트 코드를 추가적으로 작성하는 것이기 때문에 초기에는 시간이 더 드는 것처럼 느껴질 수 있다. 하지만 장기적으로 보았을 때 전체 개발 시간은 절약된다. 코드량이 많아지고 기능이 서로 얽히게 되었을 때, 테스트로 정상 동작 여부를 단번에 확인할 수 있기 때문이다. 명령어 한 줄로 방금 추가한 코드가 앱 전체의 기존 기능을 해치지 않았는지 보증받을 수 있다는 것은 정말 awesome 한 일이다. 테스트 코드 만세!

 

 

무엇을 테스트할까

프론트엔드 테스트는 무엇을 테스트할지에 따라서 크게 단위 테스트, 통합 테스트, E2E로 나눌 수 있다. 테스트 코드 작성 또한 비용이기 때문에 무엇을 테스트할지도 고민이 되었다.

테스트하지 않을 것

컴포넌트 렌더링은 리액트의 역할이라고, 테스트 커버리지에서는 후순위가 되어야 한다는 페어의 의견에 공감했다. 그래서 우리는 상태가 컴포넌트에서 제대로 표시되는지는 테스트하지 않기로 결정했다.

props.price 대신에 props.name을 표시하는 등의 실수가 있다면 걸러줘야 하지 않을까 하는 의문이 잠시 들었는데, 화면 구성이 매우 간단한 앱이어서 테스트 코드 없이 초기 코드 작성 시 충분히 커버 가능하다고 판단했다.

테스트할 것

어쨌든 가장 중요한 것은 상태가 아닐까? 따라서 상태가 제대로 관리되고 있는지를 테스트하는 것은 의미 있다고 생각했다. 결론적으로 액션이 디스패치 되었을 때 리듀서 함수가 상태를 제대로 변경하고 있는지 테스트하기로 했다.

 

 

어떤 테스트 도구를 고를까

테스트 도구에 대한 배경지식이 적고 경험의 폭도 좁은 상태여서, 기왕이면 이전에 다뤄보지 않은 테스트 툴이면 더 좋겠다는 마음으로 테스트 도구를 고민했다.

결론적으로 우리는 학습 차원에서 Jest 로 테스트를 진행하기로 결정했다.

Jest

Jest는 redux에서 추천하고, CRA에서도 언급하고 있는 테스트 도구이다. 또한, RTL(React Testing Library)은 리액트 공식 홈페이지에서 추천하는 도구이다. 필요한 테스트를 할 수 있어야 하고, 학습하는 입장에서 자료도 풍부하고 러닝 커브도 그렇게 크지 않기를 바랐는데, Jest가 이에 적합한 도구로 보였다.

RTL

RTL을 만든 Kent C. Dodds의 설명에 따르면, RTL은 Enzyme이라는 다른 테스트 도구 사용 중 정말 필요한 것만 뽑아쓰려고 하다가 만들게 된 테스트 도구라고 한다. '어? 이거 Enzyme에서 뽑아다 쓸게 아니라 그냥 만들어 써도 될 것 같은데?'하고 만든 것이다. 현재는 RTL을 React 내부에서 관리하고 있다고 한다.
(참고 영상:Understanding how react-testing-library works with Kent C. Dodds)

Storybook

이전 미션에서 사용해보았고, 다른 크루들의 코드를 참고할 수 있다는 장점이 있었다. 하지만 Top-down 식으로 Page 를 구성해 나가기로 했기 때문에 꼭 필요한 도구는 아닌 것 같았고, 스토리북 화면을 실제 브라우저 상에 렌더 되는 뷰와 비슷하게 데코레이팅 하는 과정이 필요해서 조금 번거롭기도 해서 이번 미션에서는 생략하기로 했다. Bottom-up 식으로 필요한 컴포넌트들부터 모두 만들어 놓는다면 유용할 것으로 생각된다.

Cypress

바닐라 자바스크립트 미션을 하면서 여러 번 사용해본 E2E 테스트 도구이다. E2E 테스트 코드를 작성하기엔 일정이 부족해서 선택하지 않았다. 하지만 기회가 된다면 리액트에서 다시 사용해보고 싶다.

 

 

 

참고자료

- [Testing] 3. Store와 비즈니스 로직 테스트

 

[Testing] 3. Store와 비즈니스 로직 테스트

앞서 비즈니스 로직과 컴포넌트 렌더링 구조를 분리하자고 이야기했다. 로직을 관리하게 되는 Store와 그 외의 것들을 어떻게 테스트 할 수 있을지 먼저 살펴본다. Store 꼭 store가 아니더라도 애플

jbee.io