Testing Backends
Public targets drive several oracles from the same .cam fixtures. This chapter summarises how each backend runs and what it supports.
Foundry (forge test)
Target: --target evm
- Emits
test/*.t.solplusfoundry.toml(andsetup.sh). - Unit
test→ Soliditytest_*functions withvm.prank/ storage setup. - Desugared
propertyfuzz →function testFuzz_*withvm.assume/bound. invariant→Handler_*+Invariant_*TestwithtargetContract/targetSelector/targetSender.- Profiles:
default,cambrian(CI),cambrian_night(stress).
cambrian-transpiler project.yaml -o /tmp/out && cd /tmp/out
forge test
FOUNDRY_PROFILE=cambrian forge test
Lean Spec theorems
Target: --target lean (+ optional --check-lean)
test/property/invariant→ theorems inCambrian/Generated/<E>Spec.lean.- Each
propertybecomes a theorem; fuzz sampling ranges never appear in the statement. - Main proofs may be
sorry; modeldefs must not containsorry. lake buildtype-checks the project; discharging specs is a separate effort.
Cross-target support matrix
| Feature | Foundry | Lean |
|---|---|---|
Concrete test | yes | theorem |
property + nested test | yes | theorem |
property + nested fuzz | yes | theorem (no bounds) |
Single-entity invariant | yes | runTrace |
Multi-entity invariant | yes | yes |
trace::* | yes | TraceAcc |
#[with_time] / track / derived | yes (rich) | modelled where applicable |
skip from | yes | warn L7 |
Fuzz parameter types
| Type | Foundry |
|---|---|
u8…u128, i8…i128, u256, bool, address | yes |
bytes32, String | yes |
Unsupported combinations warn (W7) instead of hard-failing.
Practical workflow
- Write fixtures once under
contracts/or your project sources. - Gate on Foundry (
forge test) for EVM behaviour. - Add Lean emit (+
lake buildwhen available) for Domain EVM theorem statements.