Agent skill
aztec-testing
Assists with testing Aztec smart contracts using the TestEnvironment. Use when writing unit tests, integration tests, or debugging test failures for Aztec contracts.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/aztec-testing
SKILL.md
Aztec Testing Skill
You are an expert in testing Aztec smart contracts. Help users write comprehensive tests using Aztec's TestEnvironment and debugging test failures.
Testing Framework Overview
Aztec provides a Noir-native testing framework using TestEnvironment that allows you to:
- Deploy contracts in a simulated environment
- Call private and public functions
- Verify state changes
- Test access control
- Simulate multiple users
Test Setup
Basic Test Structure
use aztec::{
protocol::address::AztecAddress,
test::helpers::test_environment::TestEnvironment,
};
#[test]
unconstrained fn test_example() {
// Setup
let mut env = TestEnvironment::new();
let owner = env.create_light_account();
// Deploy
let initializer = MyContract::interface().constructor(args);
let contract_address = env.deploy("MyContract").with_public_initializer(owner, initializer);
// Act - call private function
env.call_private(owner, MyContract::at(contract_address).some_function(args));
// Assert - view public state
let result = env.view_public(MyContract::at(contract_address).view_function());
assert(result == expected);
}
Account Types
// Light account - fast, limited features (use for most tests)
let owner = env.create_light_account();
// Contract account - full features including authwit support (slower)
let owner = env.create_contract_account();
Deployment Options
// Deploy with public initializer
let address = env.deploy("MyContract").with_public_initializer(owner, initializer);
// Deploy with private initializer
let address = env.deploy("MyContract").with_private_initializer(owner, initializer);
// Deploy without initializer
let address = env.deploy("MyContract").without_initializer();
Common Testing Patterns
Testing Private Functions
#[test]
unconstrained fn test_private_transfer() {
let mut env = TestEnvironment::new();
let alice = env.create_light_account();
let bob = env.create_light_account();
// Deploy and setup
let contract_address = deploy_token(&mut env, alice);
// Mint to alice first
env.call_private(alice, Token::at(contract_address).mint_private(alice, 100));
// Transfer from alice to bob
env.call_private(alice, Token::at(contract_address).transfer(bob, 50));
// Verify balances using simulate_utility for unconstrained reads
let alice_balance = env.simulate_utility(Token::at(contract_address).balance_of_private(alice));
let bob_balance = env.simulate_utility(Token::at(contract_address).balance_of_private(bob));
assert(alice_balance == 50);
assert(bob_balance == 50);
}
Testing Public Functions
#[test]
unconstrained fn test_public_mint() {
let mut env = TestEnvironment::new();
let admin = env.create_light_account();
let user = env.create_light_account();
let contract_address = deploy_token(&mut env, admin);
// Admin mints tokens
env.call_public(admin, Token::at(contract_address).mint_public(user, 1000));
// Verify balance
let balance = env.view_public(Token::at(contract_address).balance_of_public(user));
assert(balance == 1000);
}
Testing Access Control
#[test(should_fail)]
unconstrained fn test_unauthorized_mint() {
let mut env = TestEnvironment::new();
let admin = env.create_light_account();
let attacker = env.create_light_account();
let contract_address = deploy_token(&mut env, admin);
// Non-admin tries to mint - should fail
env.call_public(attacker, Token::at(contract_address).mint_public(attacker, 1000));
}
Testing Private <> Public Communication
#[test]
unconstrained fn test_public_to_private() {
let mut env = TestEnvironment::new();
let user = env.create_light_account();
let contract_address = deploy_token(&mut env, user);
// Give user some public tokens
env.call_public(user, Token::at(contract_address).mint_public(user, 100));
// Move tokens from public to private
env.call_private(user, Token::at(contract_address).public_to_private(50));
// Verify balances in both domains
let public_balance = env.view_public(Token::at(contract_address).balance_of_public(user));
let private_balance = env.simulate_utility(Token::at(contract_address).balance_of_private(user));
assert(public_balance == 50);
assert(private_balance == 50);
}
Testing Best Practices
1. Test Isolation
- Each test should be independent
- Don't rely on state from other tests
- Use fresh TestEnvironment for each test
2. Test Coverage
- Happy path scenarios
- Edge cases (zero amounts, max values)
- Access control violations
- Invalid inputs
3. Descriptive Test Names
#[test]
fn test_transfer_succeeds_with_sufficient_balance() { }
#[test(should_fail)]
fn test_transfer_fails_with_insufficient_balance() { }
4. Helper Functions
Create reusable helpers for common setup:
unconstrained fn deploy_token(env: &mut TestEnvironment, admin: AztecAddress) -> AztecAddress {
let initializer = Token::interface().constructor(admin);
env.deploy("Token").with_public_initializer(admin, initializer)
}
Debugging Test Failures
Common Issues
-
"Not authorized" errors
- Check if you've called
env.impersonate(correct_user) - Verify the user has the required role
- Check if you've called
-
State not updating
- Ensure you're using the right context (
.private()vs.public()) - Check that enqueued calls are being processed
- Ensure you're using the right context (
-
Note not found
- Make sure notes were created before consumption
- Verify the note owner is correct
-
Assertion failures
- Add print statements to debug values
- Check for off-by-one errors
- Verify expected vs actual values
Running Tests
# Run all tests
aztec test
# Run specific test
aztec test --test-name test_transfer
# Run with verbose output
aztec test --show-output
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?