Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Testing

Use deterministic models and the production-request guard for safe tests.

TestModel

#![allow(unused)]
fn main() {
use std::sync::Arc;

use starweaver_agent::{AgentBuilder, TestModel};

async fn example() -> Result<(), starweaver_agent::AgentError> {
let test_model = Arc::new(TestModel::with_text("test response"));
let agent = AgentBuilder::new(test_model).build();

let result = agent.run("hello").await?;
assert_eq!(result.output, "test response");
Ok(())
}
}

Scoped override

#![allow(unused)]
fn main() {
use std::sync::Arc;

use starweaver_agent::{AgentBuilder, TestModel};

async fn example() -> Result<(), starweaver_agent::AgentError> {
let production_agent = AgentBuilder::new(Arc::new(TestModel::with_text("prod"))).build();
let test_agent = production_agent
    .override_config()
    .model(Arc::new(TestModel::with_text("test")))
    .build();

let result = test_agent.run("hello").await?;
assert_eq!(result.output, "test");
Ok(())
}
}

Production-request guard

#![allow(unused)]
fn main() {
use starweaver_model::block_real_model_requests;

let _guard = block_real_model_requests();
assert!(!starweaver_model::allow_real_model_requests());
}

Run validation with:

make fmt-check && make check && make test

Coverage

CI runs grouped line coverage gates with cargo-llvm-cov.

cargo install cargo-llvm-cov
make coverage-core
make coverage-agent
make coverage-service
make coverage-ci
make coverage

Default acceptance gates are 95% for core contract paths, 90% for agent SDK contract paths, and 80% for CLI/service paths. Core and agent gates also enforce measured coverage floors over their full package groups. make coverage-ci cleans and collects one workspace profile set before generating the three package-scoped gate reports. The dedicated coverage workflow reuses that collection to generate target/llvm-cov/lcov.info and upload the LCOV artifact.

Automation validation

Repository automation runs through the Rust xtask crate and Makefile targets.

make scripts-check

Model cassette workflow

Provider replay fixtures can be recorded, scrubbed, and imported through repository scripts. The workflow records a live provider response, scrubs secrets and unstable ids, then imports a deterministic replay fixture.

make record-model-cassette ARGS="request.json --provider openai_chat --output cassette.json"
make scrub-model-cassette ARGS="cassette.json --output cassette.scrubbed.json"
make import-model-cassette ARGS="cassette.scrubbed.json"
make replay-check

request.json should include the canonical request fields used by replay fixtures: model, history, and expected_provider_request. Add expected_response or expected_error before importing a replay fixture. Use --mock-response response.json for deterministic script tests and --dry-run to inspect the resolved provider request.