Docs/Testing
Testing Guide
Test your AutoLoop contracts locally with Anvil and the full E2E test suite.
Unit Tests (Foundry)
AutoLoop contracts ship with Foundry tests. To run them:
cd autoloop
forge testThe test suite covers:
| Test File | What It Tests |
|---|---|
AutoLoop.t.sol | Registration, funding, execution, fee calculation |
AutoLoopVRF.t.sol | VRF proof generation, verification, random word derivation |
AutoLoopSecurity.t.sol | Access control, unauthorized callers, balance checks |
HybridGame.t.sol | Hybrid VRF mode, needsVRF flag toggling |
Run a specific test:
forge test --match-test testProgressLoop -vvvvTesting Your Own Contract
Create a test file in test/:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "forge-std/Test.sol";
import "../src/AutoLoop.sol";
import "../src/AutoLoopRegistrar.sol";
import "../src/AutoLoopRegistry.sol";
import "../src/sample/NumberGoUp.sol";
contract MyContractTest is Test {
AutoLoop autoLoop;
AutoLoopRegistrar registrar;
AutoLoopRegistry registry;
NumberGoUp game;
address controller = address(0xC0);
address owner = address(0xA1);
function setUp() public {
// Deploy protocol
registry = new AutoLoopRegistry();
autoLoop = new AutoLoop(address(registry));
registrar = new AutoLoopRegistrar(address(registry));
// Deploy your contract
game = new NumberGoUp(30); // 30s interval
// Register
vm.prank(owner);
registrar.registerAutoLoop{value: 0.1 ether}(address(game));
// Register controller
autoLoop.registerController(controller);
}
function testShouldProgress() public {
// Warp time forward past interval
vm.warp(block.timestamp + 31);
assertTrue(game.shouldProgressLoop());
}
function testProgressLoop() public {
vm.warp(block.timestamp + 31);
uint256 before = game.number();
vm.prank(controller);
autoLoop.performUpdate(address(game));
assertEq(game.number(), before + 1);
}
}Run it:
forge test --match-contract MyContractTest -vvvvLocal E2E Testing with Anvil
The full end-to-end test verifies the entire stack: contracts, registration, funding, worker execution, and health monitoring.
Prerequisites
- Foundry (anvil, forge, cast)
- Node.js >= 20
- jq (for JSON parsing)
Running the E2E Test
./test-anvil-e2e.shThis script:
- Starts Anvil with 2-second block times on port 8545
- Deploys all contracts (AutoLoop, Registry, Registrar)
- Deploys NumberGoUp — a sample contract that increments a counter every 30 seconds
- Registers the contract on-chain and deposits 0.1 ETH
- Registers a controller using Anvil's well-known test key
- Starts a worker pointed at the local chain
- Verifies the health endpoint returns correct stats
- Polls
NumberGoUp.number()for up to 90 seconds, expecting it to increment - Cleans up — kills Anvil and worker processes
Expected output:
[PASS] Anvil started
[PASS] Contracts deployed
[PASS] NumberGoUp deployed at 0x...
[PASS] Contract registered and funded
[PASS] Controller registered
[PASS] Worker started, health OK
[PASS] NumberGoUp.number() incremented: 0 → 1Manual Local Testing
If you prefer to run each step manually:
# Terminal 1: Start Anvil
anvil --block-time 2
# Terminal 2: Deploy contracts
cd autoloop
forge script script/Deploy.s.sol --rpc-url http://127.0.0.1:8545 --broadcast
# Terminal 3: Start worker
cd autoloop-worker
NETWORK=anvil RPC_URL=http://127.0.0.1:8545 \
PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
npm startThen use cast to interact:
# Check if loop should progress
cast call $CONTRACT_ADDR "shouldProgressLoop()" --rpc-url http://127.0.0.1:8545
# Check current number
cast call $CONTRACT_ADDR "number()" --rpc-url http://127.0.0.1:8545Testing VRF Contracts
VRF contracts require additional setup — the controller's public key must be registered:
# Derive pkX, pkY from private key (Node.js)
node -e "
const { secp256k1 } = require('@noble/curves/secp256k1');
const pk = secp256k1.getPublicKey('YOUR_PRIVATE_KEY_HEX', false);
const x = '0x' + Buffer.from(pk.slice(1, 33)).toString('hex');
const y = '0x' + Buffer.from(pk.slice(33, 65)).toString('hex');
console.log('pkX:', x);
console.log('pkY:', y);
"
# Register the key on-chain
cast send $VRF_CONTRACT "registerControllerKey(address,uint256,uint256)" \
$CONTROLLER_ADDR $PKX $PKY \
--rpc-url http://127.0.0.1:8545 \
--private-key $DEPLOYER_KEYThe worker will then automatically generate ECVRF proofs when executing VRF-enabled contracts.
Gas Profiling
Use forge test --gas-report to see gas consumption:
forge test --gas-reportKey gas benchmarks:
| Operation | Expected Gas |
|---|---|
performUpdate (Standard) | ~90,000 |
performVRFUpdate (Full VRF) | ~240,000 |
performVRFUpdate (Hybrid, no VRF tick) | ~95,000 |
performVRFUpdate (Hybrid, VRF tick) | ~240,000 |
registerAutoLoop | ~150,000 |
registerController | ~50,000 |