test_mode()
A context manager that patchesDrakoClient in place so all policy evaluations, audit logs, hook executions, and chain verifications run offline. It also sets DRAKO_TEST_MODE=true in the environment for the duration of the block.
Signature
Parameters
Controls how HITL checkpoints are resolved inside the context:
"auto-approve"— all tools are immediately approved."auto-deny"— all tools are immediately rejected."skip"— HITL evaluation is bypassed entirely; all tools are allowed.MockHITLResolverinstance — per-tool rules (see below).
ValueError.Data loss prevention behaviour inside the context. Accepted values:
"audit" or "off".Policy enforcement level inside the context. Accepted values:
"audit" or "off".How it works
test_mode() applies the following unittest.mock.patch replacements for the duration of the with block:
| Method patched | Test behaviour |
|---|---|
DrakoClient.evaluate_policy | Returns an offline decision based on hitl. |
DrakoClient.evaluate_policy_sync | Sync version of the above. |
DrakoClient.audit_log | No-op, returns {}. |
DrakoClient.audit_log_sync | No-op, returns {}. |
DrakoClient.execute_hooks | No-op, returns {}. |
DrakoClient.execute_hooks_sync | No-op, returns {}. |
DrakoClient.verify_chain | No-op, returns {}. |
DrakoClient.verify_chain_sync | No-op, returns {}. |
Policy evaluation response shape
Insidetest_mode(), evaluate_policy and evaluate_policy_sync return a dict with the following structure:
Examples
MockHITLResolver
A pluggable resolver that lets you define per-tool approval rules for use insidetest_mode(). Useful when you want most tools approved but specific dangerous tools denied.
Signature
Parameters
Default decision for any tool not listed in
rules. Must be "approve" or "deny". Any other value raises ValueError.Mapping of tool name to action (
"approve" or "deny"). Tools listed here override default_action.How it works
Whentest_mode(hitl=resolver) is active, every call to evaluate_policy / evaluate_policy_sync resolves through MockHITLResolver.resolve():
- Looks up
tool_nameinrules. - Falls back to
default_actionif no rule matches. - Appends the call details to
resolver.call_logfor later inspection. - Returns
{"decision": "allowed"}for"approve"and{"decision": "rejected"}for"deny".
resolve() method
Name of the tool being evaluated.
DID or name of the acting agent. Recorded in
call_log.Optional context dict (not used by the resolver itself).
{"decision": "allowed" | "rejected", "reason": "test_mode:approve" | "test_mode:deny"}.
call_log
Eachresolve() call appends an entry to resolver.call_log:
call_log in assertions to verify which tools were evaluated and in what order.
Example
Helper functions
Two additional helpers are importable fromdrako.testing:
is_test_mode() -> bool — returns True when DRAKO_TEST_MODE is set to "true", "1", or "yes" in the environment.
get_hitl_default() -> str — returns the value of DRAKO_HITL_DEFAULT from the environment, or "approve" if the variable is not set.
Best practices
Always use test_mode() in CI
Always use test_mode() in CI
Without Or wrap every test with
test_mode(), governed agents will attempt to reach the Drako API. In a CI environment with no DRAKO_API_KEY set, this will produce warnings and fall back to ungoverned mode. Any real HITL checkpoints will block indefinitely.test_mode():Use MockHITLResolver to test policy enforcement
Use MockHITLResolver to test policy enforcement
Use
MockHITLResolver with default_action="deny" to verify that your agent handles blocked tools gracefully, then check call_log to confirm the right tools were evaluated.Test fail-closed behaviour
Test fail-closed behaviour
To test
governance.on_backend_unreachable: block without a live backend, use hitl="auto-deny" combined with assertions on the return value.Keep test fixtures lightweight
Keep test fixtures lightweight
test_mode() does not require a .drako.yaml file or an API key. You can call govern() inside a test_mode() context on any duck-typed crew/graph/chat object without configuring Drako at all.