January 03, 2020
앞서 프론트엔드 테스트 코드를 작성하면서 마주할 수 있는 몇 가지에 대해 이야기했다. 이번 편에서는 다시 테스트에 대한 내용으로 돌아가 앞서 다룬 이야기들을 기반으로 프론트엔드 입장에서 테스트에 대한 부분을 되짚어 보려고 한다.
테스트는 아래의 내용을 만족해야 한다.
참(True)
, 거짓(False)
을 반환해야 한다.가정
을 통해 포함한다.Arrange-Act-Assert pattern이라는 것도 있다던데, 일단 필자는 이 둘의 차이를 이해하지 못한다. 약간의 의미가 다를 뿐, 비슷하다고 생각하고 Given
, When
, Then
에 맞춰서 테스트 코드를 작성하고 있다.
test('should $1', () => {
// Given
const data = $4
// When
const result = $3
// Then
expect(result).toEqual($2)
})
테스트를 작성할 때는 위 Code Snippet을 만들어두고 1번부터 4번까지 흐름대로 작성한다.
테스트 코드를 작성하는 것이 익숙하지 않은 분이라면 위 코드 조각(snippet)을 추천한다. 테스트 코드를 작성하는 것이 익숙하지 않을 때 어떤 순서로 어떻게 작성해야하는지 계속 버벅거리게 된다. 비즈니스 코드와는 달리 그 흐름이 익숙하지 않아서 라고 생각되는데 그런 부분을 코드 작성의 순서를 강제함으로써 해결할 수 있다.
toEqual
로 작성하지만 toBe
, toBeFalsy
등이 될 수 있다.아시다시피 테스트가 작성되는 목적에 따라 그 이름이 달라진다. 각각의 테스트는 목적에 따라서 테스트 할 대상을 정하게 되고 그에 따라 특성을 갖는다.
작성한 애플리케이션에서 테스트 가능한 가장 작은 단위의 코드를 테스트하는 기법이다. 여러 작은 단위의 테스트들이 독립적으로 참, 거짓을 판단하기 때문에 테스트가 실패했을 경우, 어느 부분이 문제인지 빠르게 파악할 수 있지만 애플리케이션의 전체적인 플로우가 정상임을 보장하지는 않는다.
애플리케이션에서 두 가지 이상의 요소가 함께 상호 작용할 때, 개발자가 의도한 대로 동작하는지 테스트하는 기법이다. 프론트엔드 개발 환경에서 봤을 때, Store에 연결(connect)된 Component를 테스트하는 경우를 예로 들 수 있을 것 같다.
하지만 두 가지 이상의 요소가 함께 상호 작용하는 부분은 맞지만 하나의 가정을 테스트하기 때문에 이것을 통합 테스트라고 할 수 있을지 의문이다. 어쩌면 유닛 테스트와 통합 테스트의 경계는 사실 모호한 것일 수 있다.
기능 테스트(Funtional Test)라고도 불리는 이 테스팅 기법은 말 그대로 끝에서 끝까지 테스트하는 기법이다. 사용자가 직접 애플리케이션을 사용하는 것처럼 동작하도록 스크립트를 작성하고 이것을 실제 실행시켜보면서 기대한대로 동작하는지 검증할 수 있다.
정말 멋진 테스트 방법이다. 프론트엔드 환경에서 E2E 테스트를 지원하기 위한 여러 도구들이 존재한다.(cypress, testcafe, nightwatch)
테스트 결과가 애플리케이션이 정상 동작함을 보장하는데 있어서 테스트하는 대상이 넓을수록 그 신뢰성을 보장한다. 하지만 그만큼의 ‘비용’이 들어간다. 처음 테스트 코드를 작성할 때 뿐만 아니라 운영 중에 테스트를 유지보수하는데 큰 비용이 들어간다.
여러 테스트들을 작성하여 변경 사항에 대하여 촘촘한 그물망을 만드는 것이 좋아보인다. 하지만 ROI를 계산해봤을 때, 그것이 과연 맞는지 생각해볼 필요가 있다.
테스트를 하기 전 비즈니스 설계가 제대로 되어야 한다. 앞서 컴포넌트 렌더링과 관련된 단위 테스트는 작성하지 않겠다고 선언했다.
그런데 컴포넌트에 비즈니스 로직이 들어가게 되면 그 부분은 테스트를 수 없게 되며 발생할 수 있는 버그로부터 안전하다는 것을 보장받을 수 없게 된다.
자연스럽게 비즈니스 로직을 custom hooks
, middleware
, selector
, reducer
로 옮기게 되고 컴포넌트는 그저 화면을 그리는 일만 하게 된다. Hooks API가 들어오면서 컴포넌트의 비즈니스 로직을 분리하여 관리할 수 있게 되었다.
물론 몇 가지 예외사항이 있을 수 있다.
그러나 대부분의 상황에 대해서는 전부 컴포넌트에서 벗어날 수 있는 비즈니스 로직이다.
이러한 비즈니스 로직들을 컴포넌트에서 걷어내야 컴포넌트 단위 테스트를 작성하지 않아도 된다.
이번 편에서도 말만 많았다. 다음 장부터는 진짜 코드로 살펴보기로 하자.
Next | 3. Store와 비즈니스 로직 테스트 |
Intro | 0. 시리즈를 들어가며 |