Backgrounds
동일한 테스트를, 입력값만 바꾸어서 실행해야 할 때가 있습니다.
데이터를 특정 형태로 변환하는 함수들이 대표적인 경우겠죠.
예를 들어, 입력받은 ms를 시간과 분 으로 분리하는 함수가 있습니다.
import { convertMsToHoursAndMinutes } from '@/utils/time';
it('ms => 시간/분 변환 함수 동작 테스트', () => {
const ms = 1800000; // 30분
const { hours, minutes } = convertMsToHoursAndMinutes(ms);
expect(hours).toBe(0);
expect(minutes).toBe(30);
});
1800000ms(30분)을 입력받으면, 0시간 30분 을 반환하는지 테스트 코드를 작성했습니다.
위 테스트를 통과했을 때... 해당 함수를 신뢰하고 사용할 수 있을까요?물론 그럴 수도 있겠지만. 아마 아닐 것입니다.
적어도 아래와 같은 케이스에 대한 테스트 정도는 작성되어 있어야 하겠죠!
- 1시간 이하의 ms 입력 시, 정상 동작 하는지
- 1시간~24시간 이내의 ms 입력 시, 정상 동작 하는지
- 24시간을 초과하는 ms 입력 시, 정상동작 하는지
시간을 변환한다는 특성상,
데이터 경곗값(0시간, 24시간)에 대한 테스트가 존재해야만, 코드 사용자가 해당 함수를 신뢰할 수 있을 것입니다.
Problems
테스트를 추가하면, 이런 형태가 됩니다.
import { convertMsToHoursAndMinutes } from '@/utils/time';
it('ms => 시간/분 변환 함수 동작 테스트', () => {
const ms1 = 1800000; // 30분
const { hours1, minutes1 } = convertMsToHoursAndMinutes(ms1);
expect(hours1).toBe(0);
expect(minutes1).toBe(30);
const ms2 = 5400000; // 1시간 30분
const { hours2, minutes2 } = convertMsToHoursAndMinutes(ms2);
expect(hours2).toBe(0);
expect(minutes2).toBe(30);
const ms3 = 9060000; // 24시간 10분
const { hours3, minutes3 } = convertMsToHoursAndMinutes(ms3);
expect(hours3).toBe(0);
expect(minutes3).toBe(30);
});
물론 테스트는 정상적으로 실행되지만,
동일한 테스트가 입력값만 변경된 채 계속해서 반복되는 모습을 볼 수 있습니다.
또한 같은 it 테스트 scope내에 존재하다 보니,
입력값과 반환값에 대한 변수명도 계속해서 다르게 유지해야 한다는 점이 굉장히 번거롭죠.
하지만 가장 큰 문제점은... → 해당 테스트의 의도를 직관적으로 파악하기 힘들다는 점!
Solutions
test.each 구문을 통해, 다양한 입력값에 대한 동일 테스트를 간결하게 구현할 수 있습니다.
(이를 파라미터화 테스트parameterized 라고 합니다)
https://jestjs.io/docs/api#testeachtablename-fn-timeout
위 테스트의 경우, 아래와 같이 수정할 수 있습니다!
import { convertMsToHoursAndMinutes } from '@/utils/time';
it.each([
{ ms: 1800000, hours: 0, minutes: 30 }, // 30분
{ ms: 5400000, hours: 1, minutes: 30 }, // 1시간 30분
{ ms: 9060000, hours: 24, minutes: 10 }, // 24시간 10분
])(
'returns expected $hours and $minutes, when $ms given',
({ ms, hours, minutes }) => {
const results = convertMsToHoursAndMinutes(ms);
expect(results.hours).toBe(hours);
expect(results.minutes).toBe(minutes);
},
);
주어진 ms를 hours와 miniutes로 변환한다는 의도가 한결 명확해진 모습!
더불어 추후 테스트 케이스를 추가하고 싶을 때도, 테스트 구현을 건드리지 않은 채 데이터만 손쉽게 추가해 줄 수 있겠죠.
'source-code > FrontEnd' 카테고리의 다른 글
WebComponent에서 styled-components 사용하기 (0) | 2024.07.10 |
---|---|
[jest] waitFor을 통한 비동기 함수 테스트 (0) | 2024.06.23 |
내가 프론트엔드에 클린 아키텍처를 도입한 이유 (0) | 2024.06.12 |
[jest] mock.calls를 통한 mock 함수 실행 테스트 개선하기 (0) | 2024.06.04 |
[jest] spyOn 사용 시 Cannot redefine property 에러 해결하기 (0) | 2024.05.30 |