Testing

Turbo has a built-in test framework. Write tests alongside your code and run them with a single command.

@test Functions

Mark any function with @test to make it a test case. Test functions must have no parameters and no return type:

fn add(a: i64, b: i64) -> i64 { a + b }

@test fn test_add() {
    assert_eq(add(2, 3), 5)
    assert_eq(add(-1, 1), 0)
    assert_eq(add(0, 0), 0)
}

@test fn test_negative() {
    assert_eq(add(-5, -3), -8)
}

Assertion Functions

FunctionDescription
assert(condition)Fails if condition is false
assert_eq(a, b)Fails if a != b
assert_ne(a, b)Fails if a == b

Running Tests

$ turbo test myfile.tb
  PASS  test_add
  PASS  test_negative
2 passed, 0 failed

Example: Testing with Assertions

fn add(a: i64, b: i64) -> i64 {
    a + b
}

fn main() {
    assert(add(2, 3) == 5)
    assert(10 > 5)
    assert(true)
    print("All assertions passed!")
}

Integration Tests

Turbo also supports integration tests using .tb + .expected file pairs:

# File: my_test.tb
fn main() {
    print("hello")
    print("world")
}

# File: my_test.expected
hello
world

The test runner compiles and runs the .tb file, captures stdout, and diffs it against the .expected file.

Expected-Error Tests

To test that the compiler correctly rejects invalid code, prefix the expected file with ERROR::

# File: type_error.expected
ERROR:type mismatch

The test passes if the compiler error output contains the pattern after ERROR:.