Skip to main content

Testing Policies

The Testing Policies workflow helps you validate that compiled policies continue to enforce the exact business and governance decisions you expect.

This is one of the most important production confidence layers in the JavaScript SDK.

The real Policy APIs that power testing are:

  • policy.assertEffect()
  • policy.evaluate()
  • policy.evaluateAction()
  • policy.policyHash()
  • policy.explain()

Core Mental Model

Input fixture -> policy -> expected decision -> regression safety

Policy tests should be treated like authorization contracts.


Fastest Assertion Pattern

The strongest testing primitive is assertEffect().

policy.assertEffect(
{
action: {
type: "deploy",
environment: "production",
},
actor: {
role: "developer",
},
snapshot: {
active_incident: false,
},
},
"require_approval",
)

If the effect changes unexpectedly, the SDK throws ActraPolicyError with:

  • expected effect
  • actual effect
  • full evaluation context

This makes failures highly actionable.


Table-Driven Tests

A highly scalable enterprise pattern.

const cases = [
{
name: "developer deploy requires approval",
input: {
action: { type: "deploy", environment: "production" },
actor: { role: "developer" },
snapshot: {},
},
expected: "require_approval",
},
{
name: "sre deploy allowed",
input: {
action: { type: "deploy", environment: "production" },
actor: { role: "sre_admin" },
snapshot: {},
},
expected: "allow",
},
]

for (const test of cases) {
policy.assertEffect(test.input, test.expected)
}

Excellent for:

  • CI regression suites
  • approval matrix validation
  • policy migrations
  • large governance programs

Direct Evaluation Tests

For full decision assertions.

const decision = policy.evaluate({
action: { type: "refund", amount: 5000 },
actor: { role: "finance" },
snapshot: { is_locked: false },
})

expect(decision.effect).toBe("allow")
expect(decision.matched_rule).toBe("finance_refund_allow")

Best when testing:

  • matched rule identity
  • approval metadata
  • analytics labels
  • audit workflows

Domain-Oriented Tests

evaluateAction() is perfect for compact fixtures.

const decision = policy.evaluateAction(
{ type: "refund", amount: 1000 },
{ role: "support" },
{ is_locked: false },
)

This keeps test inputs easy to read.


Debugging Failed Tests

Use policy.explain() immediately after assertion failures.

try {
policy.assertEffect(input, "allow")
} catch {
policy.explain(input)
throw new Error("policy regression")
}

This is the fastest way to diagnose:

  • wrong actor role
  • missing snapshot fields
  • schema drift
  • incorrect action mapping
  • changed governance behavior

Policy Hash Regression Safety

A very strong rollout technique.

const hash = policy.policyHash()
expect(hash).toBe(expectedHash)

Useful for:

  • deployment verification
  • artifact integrity
  • CI drift detection
  • cache invalidation
  • release promotion

Approval Workflow Tests

A critical enterprise pattern.

policy.assertEffect(
{
action: {
type: "transfer_funds",
amount: 500000,
},
actor: {
role: "finance_analyst",
},
snapshot: {
already_approved: false,
},
},
"require_approval",
)

This should be mandatory for:

  • finance systems
  • HR approvals
  • production deploys
  • destructive operations

CI Recommendations

Recommended CI layers:

  1. table-driven rule tests
  2. approval boundary tests
  3. policy hash checks
  4. explain on failure
  5. shadow rollout with audit()

This creates extremely safe governance rollouts.


Best Practices

Test business boundaries

Always test:

  • threshold values
  • role boundaries
  • tenant isolation
  • production environments
  • destructive actions

Test negative paths

Include:

  • explicit blocks
  • missing snapshot state
  • invalid roles
  • approval-required flows

Track policy hash in CI

This is excellent for detecting accidental policy drift.


Production Mental Model

Policy fixture
-> assert expected effect
-> explain failures
-> track hash
-> ship safely

This is how teams build trust in governed runtime decisions.


Next Steps

  • Add CI Governance Validation
  • Use Observability & Audit
  • Combine with Explain & Debugging
  • Roll out using audit() shadow mode