테스팅
테스팅 (Testing)
언어 모델을 쓰는 코드를 테스트하는 건 까다로워요. 모델은 비결정적이고, 실제로 호출하면 느리고 비용도 들기 때문이죠. AI SDK Core는 이런 문제를 풀도록 목(mock) 제공자와 테스트 헬퍼를 제공합니다. 이걸 쓰면 실제 모델 제공자를 호출하지 않고도 AI SDK를 쓰는 코드를 반복 가능하고 결정적으로 단위 테스트할 수 있어요.
출처: 공식문서
본문
ai/test에서 다음 헬퍼를 가져올 수 있어요.
MockEmbeddingModelV4: 임베딩 모델 v4 명세를 따르는 목 임베딩 모델.MockLanguageModelV4: 언어 모델 v4 명세를 따르는 목 언어 모델.mockId: 증가하는 정수 ID를 반환합니다.mockValues: 호출할 때마다 값 배열을 순회하며 반환하고, 배열이 끝나면 마지막 값을 반환합니다.
ai에서 가져오는 simulateReadableStream을 쓰면 지연이 있는 읽기 가능한 스트림을 흉내 낼 수도 있어요.
이런 목 제공자와 테스트 헬퍼 덕분에 AI SDK의 출력을 통제할 수 있어서, 실제 언어 모델 제공자를 부르지 않고도 코드를 반복 가능하고 결정적으로 검증할 수 있습니다.
예시
AI Core 함수와 테스트 헬퍼를 단위 테스트에서 함께 쓰는 방법을 볼게요.
generateText
import { generateText } from 'ai';
import { MockLanguageModelV4 } from 'ai/test';
const result = await generateText({
model: new MockLanguageModelV4({
doGenerate: async () => ({
content: [{ type: 'text', text: `Hello, world!` }],
finishReason: { unified: 'stop', raw: undefined },
usage: {
inputTokens: { total: 10, noCache: 10, cacheRead: undefined, cacheWrite: undefined },
outputTokens: { total: 20, reasoning: undefined },
},
warnings: [],
}),
}),
prompt: 'Hello, test!',
});
streamText
import { streamText, simulateReadableStream } from 'ai';
import { MockLanguageModelV4 } from 'ai/test';
const result = streamText({
model: new MockLanguageModelV4({
doStream: async () => ({
stream: simulateReadableStream({
chunks: [
{ type: 'text-start', id: 'text-1' },
{ type: 'text-delta', id: 'text-1', delta: 'Hello' },
{ type: 'text-delta', id: 'text-1', delta: ', ' },
{ type: 'text-delta', id: 'text-1', delta: 'world!' },
{ type: 'text-end', id: 'text-1' },
{
type: 'finish',
finishReason: { unified: 'stop', raw: undefined },
logprobs: undefined,
usage: {
inputTokens: { total: 3, noCache: 3, cacheRead: undefined, cacheWrite: undefined },
outputTokens: { total: 10, text: 10, reasoning: undefined },
},
},
],
}),
}),
}),
prompt: 'Hello, test!',
});
Output과 함께 쓰는 generateText
import { generateText, Output } from 'ai';
import { MockLanguageModelV4 } from 'ai/test';
import { z } from 'zod';
const result = await generateText({
model: new MockLanguageModelV4({
doGenerate: async () => ({
content: [{ type: 'text', text: `{"content":"Hello, world!"}` }],
finishReason: { unified: 'stop', raw: undefined },
usage: {
inputTokens: { total: 10, noCache: 10, cacheRead: undefined, cacheWrite: undefined },
outputTokens: { total: 20, reasoning: undefined },
},
}),
}),
prompt: 'Hello, test!',
output: Output.object({ schema: z.object({ content: z.string() }) }),
});
더 알아보기
- 목 헬퍼와 테스트 헬퍼의 API 레퍼런스
- 구조화된 데이터 생성(Generating Structured Data)의 출력 스키마
- 구조화된 출력 검증에 쓰는 스키마 라이브러리(Zod 등)