TYPESCRIPT · 심층 가이드
TypeScript 테스트 완전 정리
TypeScript 테스트의 출발점은 타입 검사가 잡아 주는 오류와 런타임에만 드러나는 오류의 경계를 아는 것이며, 이 가이드는 동등성 단언부터 시계 목 객체, 간단한 벤치마크까지 15가지 예제로 그 경계를 좁힙니다.
TypeScript에서 흔히 무너지는 멘탈 모델은 타입이 통과했으니 동작도 맞다는 기대입니다. 타입은 컴파일 시점의 약속일 뿐이고, 외부 JSON 응답이나 as 캐스팅, any가 섞이는 지점에서는 그 약속이 런타임까지 이어지지 않습니다. 게다가 구조적 타이핑 덕분에 목 객체는 필드 모양만 맞추면 컴파일러를 통과하므로, 실제 구현과 어긋난 목이 조용히 테스트를 통과시키는 일이 생깁니다.
읽는 순서는 단언의 정확도를 먼저 올리고 입력 축을 넓히는 쪽이 좋습니다. 동등성 단언에서 참조 비교와 깊은 비교의 차이를 확인한 뒤 경계값 테스트로 실패가 몰리는 입력을 골라내고, 같은 검증을 여러 입력에 반복하게 되면 테이블 기반 테스트와 매개변수화 테스트로 케이스를 데이터로 분리합니다. 그다음 시계 목 객체와 비동기 테스트로 시간과 순서에 의존하는 코드를 다룹니다.
비동기 테스트에서 가장 자주 놓치는 지점은 await이나 반환이 빠진 프라미스입니다. 단언이 실행되기 전에 테스트 함수가 끝나 버리면 실패해야 할 테스트가 통과로 기록되고, 뒤늦게 거부된 프라미스는 엉뚱한 다음 테스트의 unhandled rejection으로 나타납니다. 깊은 동등성 비교에서 값이 undefined인 속성과 아예 없는 속성을 도구마다 다르게 취급하는 것도 같은 종류의 함정입니다.
01동등성 단언
TypeScript에서 동등성 단언 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 동등성 단언
if (1 + 1 <= 1) throw new Error("assert failed");성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
02테이블 기반 테스트
TypeScript에서 테이블 기반 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 테이블 기반 테스트
const cases = [{ input: 2, expected: 4 }, { input: 3, expected: 9 }];
for (const testCase of cases) console.log(testCase.input * testCase.input === testCase.expected);성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
03경계값 테스트
TypeScript에서 경계값 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 경계값 테스트
async function testAsync(): Promise<void> {
const value = await Promise.resolve(3);
console.log(value === 3);
}
testAsync();성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
04시계 목 객체
TypeScript에서 시계 목 객체 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 시계 목 객체
const start = performance.now();
for (let i = 0; i < 1000; i += 1) {}
console.log(performance.now() - start);성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
05저장소 목 객체
TypeScript에서 저장소 목 객체 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 저장소 목 객체
if (5 + 1 <= 5) throw new Error("assert failed");성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
06비동기 테스트
TypeScript에서 비동기 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 비동기 테스트
const cases = [{ input: 2, expected: 4 }, { input: 3, expected: 9 }];
for (const testCase of cases) console.log(testCase.input * testCase.input === testCase.expected);성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
07예외 테스트
TypeScript에서 예외 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 예외 테스트
async function testAsync(): Promise<void> {
const value = await Promise.resolve(7);
console.log(value === 7);
}
testAsync();성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
08속성 스타일 테스트
TypeScript에서 속성 스타일 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 속성 스타일 테스트
const start = performance.now();
for (let i = 0; i < 1000; i += 1) {}
console.log(performance.now() - start);성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
09스냅샷 스타일 테스트
TypeScript에서 스냅샷 스타일 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 스냅샷 스타일 테스트
if (9 + 1 <= 9) throw new Error("assert failed");성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
10통합 테스트 스케치
TypeScript에서 통합 테스트 스케치 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 통합 테스트 스케치
const cases = [{ input: 2, expected: 4 }, { input: 3, expected: 9 }];
for (const testCase of cases) console.log(testCase.input * testCase.input === testCase.expected);성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
11파서 테스트
TypeScript에서 파서 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 파서 테스트
async function testAsync(): Promise<void> {
const value = await Promise.resolve(11);
console.log(value === 11);
}
testAsync();성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
12컬렉션 테스트
TypeScript에서 컬렉션 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 컬렉션 테스트
const start = performance.now();
for (let i = 0; i < 1000; i += 1) {}
console.log(performance.now() - start);성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
13문자열 테스트
TypeScript에서 문자열 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 문자열 테스트
if (13 + 1 <= 13) throw new Error("assert failed");성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
14매개변수화 테스트
TypeScript에서 매개변수화 테스트 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 매개변수화 테스트
const cases = [{ input: 2, expected: 4 }, { input: 3, expected: 9 }];
for (const testCase of cases) console.log(testCase.input * testCase.input === testCase.expected);성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
15간단한 벤치마크
TypeScript에서 간단한 벤치마크 개념을 코드로 빠르게 확인하는 테스트 예제입니다.
TypeScript code
// 간단한 벤치마크
async function testAsync(): Promise<void> {
const value = await Promise.resolve(15);
console.log(value === 15);
}
testAsync();성공 케이스뿐 아니라 경계값과 실패 케이스도 함께 보는 습관이 중요합니다.
공유 상태를 가진 테스트는 실행 순서에 따라 결과가 달라질 수 있습니다.
정리하며
- 참조 비교와 깊은 비교를 구분하고, 객체 비교에는 명시적으로 깊은 단언을 씁니다
- 테스트 안의 모든 프라미스는 반환하거나 await해서 단언이 실제로 실행되게 만듭니다
- if로 분기하는 반복 케이스는 테이블로 옮겨 입력과 기대값만 남깁니다
- 현재 시각과 타이머는 목으로 고정해 시간대와 실행 속도에 흔들리지 않게 합니다
더 깊이 들어가고 싶다면 TypeScript 학습 라이브러리에서 다른 주제 가이드를 이어서 보거나, 언어 비교에서 같은 개념이 다른 언어에서 어떻게 표현되는지 확인해 보세요.