Skip to main content
Attesta is designed to be testable from day one. Every component — scorers, renderers, challenges, and the audit logger — uses protocol-based interfaces that are trivial to mock. This guide covers testing patterns from unit tests through integration tests.

Auto-Approve in Tests

For Python, the simplest approach is relying on no-TTY behavior: in CI environments, stdin is not a TTY, so Attesta automatically uses _DefaultRenderer (auto-approve).
In TypeScript, no-TTY behavior defaults to deny. For CI tests in TypeScript, provide a test renderer that approves or denies deterministically.

Mock Renderers

For explicit control over approval outcomes, use mock renderers.

ApproveAllRenderer

A renderer that approves every action, regardless of risk level:

DenyAllRenderer

A renderer that denies every action:

RecordingAuditLogger

An audit logger that records entries in memory for assertions:

Testing Gated Functions

Test That Approved Actions Execute

Test That Denied Actions Raise

Test Risk Level Assignment

Test with Async Functions


Testing Custom Scorers

Unit Testing a Scorer

Testing DefaultRiskScorer Factors

Testing Composite Scorers


Testing Custom Challenges

Mock the I/O Layer

Challenges that use input() need mocking in tests:

Test ChallengeResult Details


Testing the Full Pipeline

Integration Test with evaluate()

Integration Test with Trust Engine


Testing with from_config()

Test that your YAML configuration loads correctly:

Pytest Configuration

Add these fixtures to your conftest.py for reuse across tests:
conftest.py
Put ApproveAllRenderer, DenyAllRenderer, and RecordingAuditLogger in a shared test utilities module. They are useful across your entire test suite, not just Attesta-specific tests.

Summary

Protocols

Protocol definitions for mock implementation

Production Deployment

Deploy with confidence after thorough testing