
Security News
Feross on the 10 Minutes or Less Podcast: Nobody Reads the Code
Socket CEO Feross Aboukhadijeh joins 10 Minutes or Less, a podcast by Ali Rohde, to discuss the recent surge in open source supply chain attacks.
@agentforge/testing
Advanced tools
Testing utilities for TypeScript AI agents, including mock LLMs, mock tools, state builders, fixtures, and workflow assertions.
Testing utilities and helpers for the AgentForge framework
Complete testing toolkit | Full TypeScript support | Comprehensive documentation
npm install --save-dev @agentforge/testing
# or
pnpm add -D @agentforge/testing
# or
yarn add -D @agentforge/testing
import { describe, it, expect } from 'vitest';
import {
createMockLLM,
createMockTool,
createStateBuilder,
createAgentTestRunner,
assertMessageContains,
} from '@agentforge/testing';
describe('My Agent', () => {
it('should respond to greetings', async () => {
// Create mock LLM
const llm = createMockLLM({
responses: ['Hello! How can I help you?']
});
// Create test state
const state = createStateBuilder()
.addHumanMessage('Hi')
.build();
// Run agent
const runner = createAgentTestRunner(agent);
const result = await runner.run(state);
// Assert
expect(result.passed).toBe(true);
assertMessageContains(result.messages, 'Hello');
});
});
Create mock language models for testing:
import { createMockLLM, createEchoLLM, createErrorLLM } from '@agentforge/testing';
// Basic mock with predefined responses
const llm = createMockLLM({
responses: ['Response 1', 'Response 2']
});
// Echo LLM (echoes input)
const echoLLM = createEchoLLM();
// Error LLM (always throws)
const errorLLM = createErrorLLM('Custom error message');
// Custom response generator
const customLLM = createMockLLM({
responseGenerator: (messages) => {
const lastMsg = messages[messages.length - 1];
return `You said: ${lastMsg.content}`;
}
});
Create mock tools for testing:
import { createMockTool, createEchoTool, createCalculatorTool } from '@agentforge/testing';
import { z } from 'zod';
// Basic mock tool
const tool = createMockTool({
name: 'my_tool',
schema: z.object({ input: z.string() }),
implementation: async ({ input }) => `Processed: ${input}`
});
// Echo tool
const echoTool = createEchoTool();
// Calculator tool
const calcTool = createCalculatorTool();
Build test states easily:
import { createStateBuilder } from '@agentforge/testing';
const state = createStateBuilder()
.addHumanMessage('Hello')
.addAIMessage('Hi there!')
.set('customField', 'value')
.build();
Helpful assertion functions:
import {
assertMessageContains,
assertLastMessageContains,
assertToolCalled,
assertCompletesWithin,
} from '@agentforge/testing';
// Assert message contains text
assertMessageContains(messages, 'hello');
// Assert last message contains text
assertLastMessageContains(messages, 'goodbye');
// Assert tool was called
assertToolCalled(toolCalls, 'calculator', { operation: 'add' });
// Assert completes within time
await assertCompletesWithin(async () => {
await agent.invoke(input);
}, 1000);
Pre-built test data:
import {
simpleGreeting,
multiTurnConversation,
sampleTools,
calculatorTool,
} from '@agentforge/testing';
// Use sample conversations
const messages = simpleGreeting;
// Use sample tools
const tools = sampleTools;
Run integration tests on agents:
import { createAgentTestRunner } from '@agentforge/testing';
const runner = createAgentTestRunner(agent, {
timeout: 5000,
captureSteps: true,
validateState: true,
});
const result = await runner.run({ messages: [new HumanMessage('Test')] });
expect(result.passed).toBe(true);
expect(result.executionTime).toBeLessThan(5000);
Simulate multi-turn conversations:
import { createConversationSimulator } from '@agentforge/testing';
const simulator = createConversationSimulator(agent, {
maxTurns: 5,
verbose: true,
stopCondition: (messages) => {
const lastMsg = messages[messages.length - 1];
return lastMsg.content.includes('goodbye');
}
});
const result = await simulator.simulate([
'Hello',
'What can you do?',
'Help me with a task'
]);
expect(result.completed).toBe(true);
expect(result.turns).toBe(3);
Create and compare state snapshots:
import {
createSnapshot,
assertMatchesSnapshot,
compareStates,
createStateDiff,
} from '@agentforge/testing';
// Create snapshot
const snapshot = createSnapshot(state, {
normalizeTimestamps: true,
normalizeIds: true,
excludeFields: ['_internal']
});
// Assert matches snapshot
assertMatchesSnapshot(state);
// Compare states
const isEqual = compareStates(state1, state2);
// Create diff
const diff = createStateDiff(stateBefore, stateAfter);
console.log(diff.changed); // { field: { from: 'old', to: 'new' } }
import { describe, it, expect } from 'vitest';
import {
createMockLLM,
createMockTool,
createStateBuilder,
createAgentTestRunner,
createConversationSimulator,
assertMessageContains,
assertToolCalled,
assertMatchesSnapshot,
} from '@agentforge/testing';
import { createReActAgent } from '@agentforge/patterns';
describe('ReAct Agent Integration Tests', () => {
const llm = createMockLLM({
responses: [
'I need to use the calculator tool.',
'The result is 4.'
]
});
const calculatorTool = createMockTool({
name: 'calculator',
implementation: async ({ operation, a, b }) => {
if (operation === 'add') return `${a + b}`;
return '0';
}
});
const agent = createReActAgent({
llm,
tools: [calculatorTool],
});
it('should use tools to solve problems', async () => {
const runner = createAgentTestRunner(agent, {
timeout: 5000,
captureSteps: true
});
const state = createStateBuilder()
.addHumanMessage('What is 2 + 2?')
.build();
const result = await runner.run(state);
expect(result.passed).toBe(true);
assertMessageContains(result.messages, 'calculator');
assertToolCalled(result.finalState.toolCalls, 'calculator');
});
it('should handle multi-turn conversations', async () => {
const simulator = createConversationSimulator(agent, {
maxTurns: 3,
verbose: false
});
const result = await simulator.simulate([
'Hello',
'Calculate 5 + 3',
'Thank you'
]);
expect(result.completed).toBe(true);
expect(result.turns).toBe(3);
assertMatchesSnapshot(result.messages);
});
});
createMockLLM(config?) - Create a mock LLMcreateEchoLLM() - Create an echo LLMcreateErrorLLM(message?) - Create an error LLMcreateMockTool(config?) - Create a mock toolcreateEchoTool(name?) - Create an echo toolcreateCalculatorTool() - Create a calculator toolcreateStateBuilder() - Create a state buildercreateConversationState(messages) - Create conversation statecreateReActState(config?) - Create ReAct agent statecreatePlanningState(config?) - Create planning agent stateassertMessageContains(messages, content) - Assert message contains textassertLastMessageContains(messages, content) - Assert last message contains textassertToolCalled(toolCalls, name, args?) - Assert tool was calledassertCompletesWithin(fn, maxMs) - Assert completes within timeassertStateHasFields(state, fields) - Assert state has fieldsassertMatchesSnapshot(state, config?) - Assert matches snapshotcreateAgentTestRunner(agent, config?) - Create agent test runnercreateConversationSimulator(agent, config?) - Create conversation simulatorsimpleGreeting - Simple greeting conversationmultiTurnConversation - Multi-turn conversationsampleTools - Array of sample toolscalculatorTool - Calculator toolsearchTool - Search toolMIT © 2026 Tom Van Schoor
FAQs
Testing utilities for TypeScript AI agents, including mock LLMs, mock tools, state builders, fixtures, and workflow assertions.
The npm package @agentforge/testing receives a total of 507 weekly downloads. As such, @agentforge/testing popularity was classified as not popular.
We found that @agentforge/testing demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh joins 10 Minutes or Less, a podcast by Ali Rohde, to discuss the recent surge in open source supply chain attacks.

Research
/Security News
Campaign of 108 extensions harvests identities, steals sessions, and adds backdoors to browsers, all tied to the same C2 infrastructure.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.