Unit Testing
Fe has a built-in test framework. Mark any function with #[test] and run it with fe test.
Your First Test
Section titled “Your First Test”fn max(a: u256, b: u256) -> u256 { if a > b { a } else { b }}
#[test]fn test_max() { assert(max(3, 7) == 7) assert(max(10, 2) == 10) assert(max(5, 5) == 5)}Run it:
fe test my_file.feOutput:
PASS [0.0003s] test_max
test result: ok. 1 passed; 0 failedTesting Struct Methods
Section titled “Testing Struct Methods”Test struct methods the same way — create an instance, call methods, assert results:
struct Point { x: u256, y: u256,}
impl Point { fn distance_squared(self, other: Point) -> u256 { let dx = if self.x > other.x { self.x - other.x } else { other.x - self.x } let dy = if self.y > other.y { self.y - other.y } else { other.y - self.y } dx * dx + dy * dy }}
#[test]fn test_distance() { let a = Point { x: 0, y: 0 } let b = Point { x: 3, y: 4 } assert(a.distance_squared(b) == 25)}Testing Expected Reverts
Section titled “Testing Expected Reverts”Use #[test(should_revert)] to verify that code reverts when it should. The test passes if execution reverts, and fails if it succeeds:
#[test(should_revert)]fn test_overflow_reverts() { let x: u8 = 255 let _ = x + 1 // arithmetic overflow → revert}
#[test(should_revert)]fn test_division_by_zero_reverts() { let x: u256 = 1 let _ = x / 0}
#[test(should_revert)]fn test_assert_false_reverts() { assert(false)}This is useful for verifying that safety checks (overflow, access control, assertions) actually trigger.
Assertions
Section titled “Assertions”assert(condition) reverts the test if the condition is false. Since assert takes a single bool, use comparison expressions:
#[test]fn test_assertions() { // Equality assert(add(2, 3) == 5)
// Comparison let a: u256 = 10 assert(a > 5) let b: u256 = 3 assert(b <= 3)
// Boolean logic assert(true && true) assert(!false)}What to Test
Section titled “What to Test”Pure functions and struct methods are the easiest to test because they have no side effects:
- Arithmetic helpers — fee calculations, rounding, clamping
- Data structure operations — encoding, decoding, validation
- Business logic — access control checks, state transitions
- Edge cases — zero values, max values, boundary conditions
For testing contracts with storage and message handling, see Integration Testing.