[Canvas-불꽃놀이-18] utils.js 단위 테스트

이전 글 : [Canvas-불꽃놀이-17] Jest 설정과 테스트 진행 순서

 

[Canvas-불꽃놀이-17] Jest 설정과 테스트 진행 순서

이전 글 : [Canvas-불꽃놀이-16] SparkParticle로 잔상효과 적용하기 [Canvas-불꽃놀이-16] SparkParticle로 잔상효과 적용하기이전 글 : [Canvas-불꽃놀이-15] CircleParticle 구현과 업데이트 [Canvas-불꽃놀이-15] Circ

jinsk-joy.tistory.com

 

isEven을 제외한 나머지 유틸리티 메서드에 대해 단위테스트를 진행 (Jest 문서)

 

 

utils.js 단위 테스트

utils.js 코드 전체 보기

더보기
import { PARTICLE } from "@/js/constants.js";

/**
 * @param {number} min
 * @param {number} max
 * @param {number} [decimal=2]
 * @returns {number} min과 max 사이의 소수점 decimal(기본값:2)자리의 랜덤한 소수 반환
 */
export function randomFloat(min, max, decimal = 2) {
	return parseFloat((Math.random() * (max - min) + min).toFixed(decimal));
}

/**
 * @param {number} min
 * @param {number} max
 * @returns {number} min과 max 사이의 랜덤한 정수 반환
 */
export function randomInt(min, max) {
	return Math.floor(Math.random() * (max - min + 1) + min);
}

/**
 * @param {string} [rgb] "255, 255, 210" (반드시 옆의 형식으로 기입)
 * @param {number} [opacity]
 * @returns {string} 파티클 색성에 적용할 RGBA 문자열 반환
 */
export function setRgbaColor(rgb = PARTICLE.RGB, opacity = 1) {
	return `rgba(${rgb}, ${opacity})`;
}

/**
 * @param {object} [params]
 * @param {number} [params.hue]
 * @param {number} [params.saturation]
 * @param {number} [params.lightness]
 * @returns {string} 파티클 색상애 적용할 HSLA 문자열 반환
 */
export function setHslaColor(params = {}) {
	const {
		hue = PARTICLE.HUE,
		saturation = randomInt(PARTICLE.MIN_SATURATION, PARTICLE.MAX_SATURATION),
		lightness = randomInt(PARTICLE.MIN_LIGHTNESS, PARTICLE.MAX_LIGHTNESS),
	} = params;

	return `hsla(${hue}, ${saturation}%, ${lightness}%)`;
}

/**
 * @param {number} num
 * @returns {boolean} 짝수면 true 반환, 홀수면 false 반환
 */
export function isEven(num) {
	return num % 2 === 0;
}
  • 하나의 describe로 진행하며 공통적인 안내 문구를 상수화
// 공통 안내 문구
const NOTICE_UNDEFINED = "| 파라미터 기본값 적용: 테스트: 인자에 undefined, 실사용: 인자 전달 X";

describe("utils.js 테스트", () => {
    // 테스트 코드 기입
}

 

1.  randomFloat 테스트

  • randomFloat는 주어진 범위 (min, max) 내에서 decimal에 따라 소수점 아래 자릿수를  제한한 랜덤한 부동 소수점 숫자를 생성해 반환한다.
  • 테스트 내용
    -. 전달한 인자값과 인자를 전달하지 않았을때 기본값이 제대로 적용되는지 확인한다.
    -. 다양한 범위의 테스트 케이스를 반복적으로 100번 실행하여 무작위성을 검증한다.
// NOTICE_UNDEFINED = "| 파라미터 기본값 적용: 테스트: 인자에 undefined, 실사용: 인자 전달 X";

test.each([
    { min: 1, max: 3, decimal: undefined, NOTICE_UNDEFINED },
    { min: 0.8, max: 2.5, decimal: 1, NOTICE_UNDEFINED },
    { min: -5, max: 5, decimal: 4, NOTICE_UNDEFINED },
])("randomFloat 테스트 (min: $min, max: $max, decimal: $decimal) $NOTICE_UNDEFINED", ({ min, max, decimal }) => {
    for (let i = 0; i < 100; i++) {
        const result = randomFloat(min, max, decimal);

        // result가 min 이상이며
        expect(result).toBeGreaterThanOrEqual(min);

        // result가 max 이하이고
        expect(result).toBeLessThanOrEqual(max);

        // result의 소수점 아래 자릿수가 decimal 자리인지 검증 (default는 2)
        expect(result).toBeCloseTo(result, decimal ?? 2);
    }
});

 

2. randomInt 테스트

  • randomInt는 주어진 범위 (min, max) 내에서 랜덤한 정수를 생성해 반환한다.
  • 테스트 내용
    -. -50~50 범위의 테스트 케이스를 100번 실행 하여 무작위성을 검증한다.
test("randomInt 테스트", () => {
    for (let i = 0; i < 100; i++) {
        const result = randomInt(-50, 50);
        
        // result가 -50이상 (음의 정수)
        expect(result).toBeGreaterThanOrEqual(-50);
        
        // result가 50이하며 (양의 정수)
        expect(result).toBeLessThanOrEqual(50);
        
        // result가 정수여야한다.
        expect(Number.isInteger(result)).toBe(true);
    }
});

 

3. setRgbaColor 테스트

  • setRgbaColor는 주어진 rgb, alpha(opacity)를 바탕으로 "rgba(r, g, b, a)" 형식의 문자열을 반환한다.
  • 테스트 내용
    -. 인자를 모두 전달하지 않을때 (기본값 적용 )
    -. rgb는 커스텀, opacity는 기본값일 때
    -. rgb는 기본값, opacity는 커스텀값일 때
    -. 인자를 모두 전달할 때
// NOTICE_UNDEFINED = "| 파라미터 기본값 적용: 테스트: 인자에 undefined, 실사용: 인자 전달 X";

test.each([
    { rgb: undefined, opacity: undefined, NOTICE_UNDEFINED },
    { rgb: "0, 10, 255", opacity: undefined, NOTICE_UNDEFINED },
    { rgb: undefined, opacity: 0.5, NOTICE_UNDEFINED },
    { rgb: "255, 255, 255", opacity: 0.8, NOTICE_UNDEFINED },
])("setRgbaColor 테스트(rgb: $rgb, opacity: $opacity) $NOTICE_UNDEFINED", ({ rgb, opacity }) => {
    const result = setRgbaColor(rgb, opacity);
    
    // result가 예상한 rgba 형식과 일치해야한다.
    expect(result).toBe(`rgba(${rgb ?? PARTICLE.RGB}, ${opacity ?? 1})`);
});

 

4. setHslaColor 테스트

  • setHslaColor는 주어진 hue, saturation, lightness를 바탕으로 "hsla(hue, saturation%, lightness%)" 형식의 문자열을 반환한다.
  • setHslaColor에서 파라미터에 기본값이 적용될 때 randomInt 메서드를 활용하는데 내부 캡슐화가 되어있으므로 mock 함수 적용이 불가하다.
    이미 randomInt는 이미 앞에서 검증되었으므로 기본값을 사용 시 자릿수(1~3)가 올바른지 확인하여 무작위성을 검증하도록 한다.
  • setHslaColor에서 파라미터에 커스텀 값을 받았을 때 정규식을 이용하여 hue, saturation, lightness 값을 추출할 수 있으므로 커스텀 값일 때만 일치 여부 테스트를 진행하도록 한다.
  • 테스트 내용
    -. 인자를 모두 전달하지 않을때 (기본값 적용)
    -. hue: 커스텀 값 / saturation, lightness : 기본값일 때
    -. saturation: 커스텀 값 / hue, lightness: 기본값일 때
    -. lightness: 커스텀 값 / hue, saturation: 기본값일 때
    -. 인자를 모두 전달할 때
// NOTICE_UNDEFINED = "| 파라미터 기본값 적용: 테스트: 인자에 undefined, 실사용: 인자 전달 X";

test.each([
    { hue: undefined, saturation: undefined, lightness: undefined, NOTICE_UNDEFINED },
    { hue: 100, saturation: undefined, lightness: undefined, NOTICE_UNDEFINED },
    { hue: undefined, saturation: 100, lightness: undefined, NOTICE_UNDEFINED },
    { hue: undefined, saturation: undefined, lightness: 100, NOTICE_UNDEFINED },
    { hue: 5, saturation: 20, lightness: 100, NOTICE_UNDEFINED },
])("setHslaColor 테스트 (hue: $hue, saturation: $saturation, lightness: $lightness) $NOTICE_UNDEFINED", ({ hue, saturation, lightness }) => {
    const result = setHslaColor({ hue, lightness, saturation });
    
    // 예상 결과를 정규식으로 표현
    // 기본값이 randomInt로 설정되는 saturation, lightness는 1~3자리 숫자로 가정
    const expectResult = new RegExp(`^hsla\\(${hue ?? PARTICLE.HUE}, ${saturation ?? "\\d{1,3}"}%, ${lightness ?? "\\d{1,3}"}%\\)$`);
    
    // 결과값이 예상한 형식과 일치하는지 검증
    expect(result).toMatch(expectResult);
    
    // hue, saturation, lightness 값을 추출하여 int로 변환한다.
    const hslArr = result.match(/\d+/g).map((value) => parseInt(value, 10));
    const hslObj = { h: hslArr[0], s: hslArr[1], l: hslArr[2] };
    
    // 커스텀 값일 때만 일치 여부를 확인한다.
    if (hue !== undefined) expect(hslObj.h).toBe(hue);
    if (saturation !== undefined) expect(hslObj.s).toBe(saturation);
    if (lightness !== undefined) expect(hslObj.l).toBe(lightness);
});

 

실행 결과

전체 테스트 실행

npm test

 

utils 파일만 테스트 진행

npx jest ./__test__/utils.test.js

 

Github Repo
 

GitHub - jinsk9268/text-fireworks

Contribute to jinsk9268/text-fireworks development by creating an account on GitHub.

github.com