Chapter 11 · Test transitions and regression boundaries
Testing a graph need not call a paid model every time. Stabilize branches, updates, and rejection paths before separate model integration and quality evaluation.
Mechanics and design choices
Unit tests inspect node updates; graph integration tests inspect outcomes and paths; model evaluations assess groundedness and tool choice rather than exact wording. This example builds a fresh graph for each test to avoid shared checkpointers, stores, or mutable globals leaking between cases.
Example
import unittest
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
class State(TypedDict):
text: str
accepted: bool
def validate(state: State):
return {"accepted": bool(state["text"].strip())}
def make_graph():
builder = StateGraph(State)
builder.add_node("validate", validate)
builder.add_edge(START, "validate")
builder.add_edge("validate", END)
return builder.compile()
class GraphTests(unittest.TestCase):
def test_node(self):
self.assertEqual(validate({"text": "ok"}), {"accepted": True})
def test_graph_cases(self):
for text, expected in [("", False), (" ", False), ("hello", True)]:
with self.subTest(text=text):
result = make_graph().invoke({"text": text, "accepted": False})
self.assertEqual(result["accepted"], expected)
self.assertEqual(result["text"], text)
if __name__ == "__main__":
unittest.main()Run and verify
Save as test_graph.py and run python test_graph.py; expect OK. Standard-library unittest avoids an extra pytest dependency. Passing verifies these deterministic contracts, not model quality.
Pitfalls
Do not test only success. Resume, exhausted retries, unknown tools, duplicate requests, and empty retrieval results reveal production defects. Use fixtures rather than changing public pages.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. Must unit tests request a model?
2. Why build a fresh graph per test?
3. Should model quality rely only on exact strings?
4. Should empty retrieval be tested?
Hands-on exercises
- Reject non-string input explicitly at the application boundary.
- Automate approve and reject cases from the interrupt example.
- Define cost limits and acceptance criteria for live-model integration tests.
Official references
Verified on: 2026-09-17.