llmtest

package
v0.1.14-update.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package llmtest provides utilities for testing LLM implementations.

Inspired by Go's testing/fstest package, llmtest offers a simple, backend-independent way to verify that LLM implementations conform to the expected interfaces and behaviors.

Design Philosophy

Following the principles of testing/fstest:

  • Minimal API surface - one main function (TestLLM)
  • Automatic capability discovery - no configuration required
  • Comprehensive by default - tests all detected capabilities
  • Interface testing - works with any llms.Model implementation
  • Simple usage pattern - just pass the model to test

Usage

Testing an LLM implementation is straightforward:

func TestMyLLM(t *testing.T) {
    llm, err := mylllm.New()
    if err != nil {
        t.Fatal(err)
    }
    llmtest.TestLLM(t, llm)
}

Automatic Capability Discovery

The package automatically detects and tests supported capabilities:

  • Basic operations (Call, GenerateContent)
  • Streaming (unless the call site passes WithoutStreaming)
  • Tool/Function calling (probed with a test tool; a door that takes the tools must answer with a call unless the call site passes WithoutToolCalls)
  • A door that needs particular options to answer at all, such as the output budget a thinking model spends before its first word, declares them with WithCallOptions; every checked request carries them
  • Token counting (if usage information provided)
  • Context caching (if implemented)

Mock Implementation

A MockLLM is provided for testing without making actual API calls. It answers in prose and never calls a tool, so it declares WithoutToolCalls:

mock := &llmtest.MockLLM{
    GenerateResponse: &llms.ContentResponse{
        Choices: []*llms.ContentChoice{{Content: "Hello"}},
    },
}
llmtest.TestLLM(t, mock, llmtest.WithoutToolCalls())

Parallel Testing

All tests run in parallel by default for better performance:

  • Core tests (Call, GenerateContent) run concurrently
  • Capability tests run in parallel when detected
  • Safe for concurrent execution with independent contexts

Provider Coverage

The package is used to test all LangChain Go providers: anthropic, bedrock, fake, googleai, huggingface, mistral, ollama, openai, and more.

Package llmtest provides support for testing LLM implementations.

Following the design of testing/fstest, this package provides a simple TestLLM function that verifies an LLM implementation behaves correctly.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func TestLLM

func TestLLM(t *testing.T, model llms.Model, opts ...Option)

TestLLM tests an LLM implementation. It performs basic operations and checks that the model behaves correctly. It automatically discovers and tests capabilities by probing the model.

If TestLLM finds any misbehaviors, it reports them via t.Error/t.Fatal.

Typical usage inside a test:

func TestLLM(t *testing.T) {
    llm, err := mylllm.New(...)
    if err != nil {
        t.Fatal(err)
    }
    llmtest.TestLLM(t, llm)
}

func TestLLMWithOptions

func TestLLMWithOptions(t *testing.T, model llms.Model, opts TestOptions, expected ...string)

TestLLMWithOptions tests an LLM with specific test options.

func ValidateLLM

func ValidateLLM(model llms.Model) error

ValidateLLM checks if a model satisfies basic requirements without running tests. It returns an error describing what's wrong, or nil if the model is valid.

Types

type MockLLM

type MockLLM struct {
	// Response to return from Call
	CallResponse string
	CallError    error

	// Response to return from GenerateContent
	GenerateResponse *llms.ContentResponse
	GenerateError    error

	CallCount     int
	GenerateCount int
	LastPrompt    string
	LastMessages  []llms.MessageContent
	// contains filtered or unexported fields
}

MockLLM provides a simple mock implementation for testing.

func (*MockLLM) Call

func (m *MockLLM) Call(ctx context.Context, prompt string, options ...llms.CallOption) (string, error)

Call implements llms.Model

func (*MockLLM) GenerateContent

func (m *MockLLM) GenerateContent(ctx context.Context, messages []llms.MessageContent, options ...llms.CallOption) (*llms.ContentResponse, error)

GenerateContent implements llms.Model

type Option

type Option func(*TestOptions)

Option declares, at the call site, what the door under test cannot do or what it needs to be called with.

func WithCallOptions

func WithCallOptions(opts ...llms.CallOption) Option

WithCallOptions declares options the door needs on every request to answer at all, such as the output budget a thinking model spends on thoughts before its first word. The suite appends them after its own, so they override its budgets and other defaults, while the Streaming test still installs its text collector last and the tool probe stays a pure capability probe. Every answer is held to the same checks as before.

func WithoutStreaming

func WithoutStreaming() Option

WithoutStreaming declares a door that does not deliver a streaming callback, so the suite must not hold it to that contract.

func WithoutToolCalls

func WithoutToolCalls() Option

WithoutToolCalls declares a door that takes tools but never answers with a call, so the suite must not hold it to that contract.

type TestOptions

type TestOptions struct {
	// Timeout for each test operation
	Timeout time.Duration

	// Skip specific test categories
	SkipCall            bool
	SkipGenerateContent bool
	SkipStreaming       bool
	SkipToolCalls       bool

	// Custom test prompts
	TestPrompt   string
	TestMessages []llms.MessageContent

	// For providers that need special options
	CallOptions []llms.CallOption
}

TestOptions configures test execution.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL