agenttest
pytest for AI agents. Catch silent agent failures before they reach production.
⚡ The Problem
AI agents fail in non-traditional ways: hallucinations, infinite tool loops, persona drift, broken JSON outputs, and unhandled tool outages. Standard unit tests fail to catch these behavioral issues, and building custom test harnesses takes weeks.
agenttest brings automated, production-grade behavioral testing to AI agent pipelines. It integrates seamlessly into standard pytest workflows with zero hassle.
📦 Install
pip install agenttest
agenttest init
Running agenttest init auto-detects your agent framework and configures your agenttest.config.json.
🚀 Quick Start
from agenttest import agent_test, mock_tool_failure
@agent_test
def test_agent_is_factual_and_efficient():
result = my_agent.run("What is the capital of France?")
assert result.contains_fact("Paris")
assert result.hallucination_score < 0.1
assert result.steps_taken <= 3
@agent_test
def test_handles_tool_failure_gracefully():
with mock_tool_failure("web_search"):
result = my_agent.run("Search for recent tech news")
assert result.gracefully_degraded == True
Run directly with pytest:
pytest
🛠️ Supported Frameworks
| Framework | Status | Trace Capture | Tool Mocking | Token Tracking |
|---|---|---|---|---|
| LangGraph | ✅ | ✅ | ✅ | ⚠️ (0) |
| CrewAI | ✅ | ✅ | ✅ | ⚠️ (0) |
| OpenAI Agents SDK | ✅ | ✅ | ✅ | ✅ |
| Anthropic SDK | ✅ | ✅ | ✅ | ✅ |
| Generic Python Agent | ✅ | ✅ | ✅ | ⚠️ (0) |
🧠 Bring Your Own Judge Model
agenttest supports multi-provider LLM-as-a-judge routing. Select your preferred judge model during initialization or in agenttest.config.json.
| Provider | Command | Env Var | Default Model | Cost |
|---|---|---|---|---|
| Anthropic | agenttest init --judge anthropic |
ANTHROPIC_API_KEY |
claude-haiku-4-5-20251001 |
Low |
| OpenAI | agenttest init --judge openai |
OPENAI_API_KEY |
gpt-4o-mini |
Low |
| Gemini | agenttest init --judge gemini |
GOOGLE_API_KEY |
gemini-1.5-flash |
Very Low |
| Ollama | agenttest init --judge ollama |
(Local instance) | llama3 |
Free |
| None | agenttest init --judge none |
(None needed) | none |
Free |
🔍 Structural Assertions (No API Key Needed)
Pure Python assertions that evaluate speed, output structure, token count, and tool usage without touching the network:
assert_word_count_between(output, min_count, max_count)— Verify word counts within inclusive limits.assert_steps_at_most(steps_taken, max_steps)— Cap maximum execution steps.assert_tool_was_called(tools_called, tool_name)— Ensure a specific tool was invoked.assert_tool_was_not_called(tools_called, tool_name)— Verify forbidden tools were avoided.assert_latency_under(latency_ms, threshold_ms)— Enforce strict response latency targets.assert_tokens_under(tokens_used, max_tokens)— Enforce token consumption budgets.assert_output_contains(output, substring)— Simple case-insensitive substring search.assert_output_matches_regex(output, pattern)— Regex pattern matching.assert_output_is_valid_json(output)— Validate JSON output syntax.assert_gracefully_degraded(result)— Ensure agent handled tool errors gracefully.
🤖 Semantic Assertions (Judge Model Required)
LLM-judged assertions powered by your configured judge provider:
assert_contains_fact(output, "Paris")— Fact verification.assert_hallucination_score(output) < 0.1— Hallucination likelihood rating (0.0 to 1.0).assert_tone_matches(output, "professional")— Tone and style checking.assert_answers_question(output, "What is Python?")— Question coverage evaluation.assert_language_matches(output, "Spanish")— Target language detection.
🧪 Tool Mocking
Simulate real-world tool failures, custom mock responses, and network delays in tests:
from agenttest import mock_tool_failure, mock_tool_response, mock_tool_latency
# Mock tool exception
with mock_tool_failure("web_search", error_message="503 Service Unavailable"):
agent.run("Fetch latest weather")
# Mock custom data return
with mock_tool_response("calculator", {"result": 42}):
agent.run("Calculate 6 * 7")
# Inject network delay (milliseconds)
with mock_tool_latency("database_query", delay_ms=500):
agent.run("Fetch user record")
⚙️ CI/CD Integration
Add this step to .github/workflows/test.yml to run automated agent testing in GitHub Actions:
name: Test Suite
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install agenttest pytest
- name: Run agenttest suite
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
pytest
🤝 Contributing
Contributions are very welcome! Please feel free to open an issue or submit a pull request on GitHub.
- Fork the repo and create your feature branch (
git checkout -b feature/my-feature). - Install development dependencies (
pip install -e .[dev]). - Run test suite (
pytest tests/ -v). - Push to branch and open a Pull Request.
📜 License
MIT License. Copyright (c) 2026. #\x00 \x00a\x00g\x00e\x00n\x00t\x00_\x00t\x00e\x00s\x00t\x00_\x00p\x00i\x00p\x00 \x00 \x00
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agenttest_ai-0.1.0.tar.gz.
File metadata
- Download URL: agenttest_ai-0.1.0.tar.gz
- Upload date:
- Size: 23.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
61646f01a108c394fa8dc999b80868c39dd05fd21d1df993ab58423be6cf6406
|
|
| MD5 |
b50badcab1e12e319e1d671d34c8c9b4
|
|
| BLAKE2b-256 |
c29cdfaffd537446313a233ba35c1de7da54a9409977f672de7a2e5159af110f
|
File details
Details for the file agenttest_ai-0.1.0-py3-none-any.whl.
File metadata
- Download URL: agenttest_ai-0.1.0-py3-none-any.whl
- Upload date:
- Size: 24.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27d08f67645136e06e2c837c29d312295f5c2d410f29b7fd10fa9c3769c0ea14
|
|
| MD5 |
9eb3232a999afce7c98f7ce8cbad6f16
|
|
| BLAKE2b-256 |
746fc3c2aba294c3a9212fe55e3fcb6dc660186c5e78dea38cfc669d28d7d15c
|