Example: writing tests
Quadrate has built-in testing support. Write tests alongside your code and run them with quad test.
Defining tests
Use the test keyword with a name and a block:
use testing
test "addition works" {
2 3 + 5 testing::assert_eq
}
test "string comparison" {
"hello" "hello" testing::assert_eq
}
Tests don't need a main function. Each test block runs independently.
Assertion functions
The testing module provides these assertions:
| Function | Description |
|---|---|
testing::assert_eq |
Assert two values are equal |
testing::assert_ne |
Assert two values are not equal |
testing::assert_true |
Assert a value is truthy (non-zero, non-empty) |
testing::assert_false |
Assert a value is falsy (zero, empty) |
testing::assert_approx_eq |
Assert two floats are approximately equal |
testing::fail |
Unconditionally fail with a message |
Examples
use testing
test "assert_eq checks equality" {
5 5 testing::assert_eq
"hello" "hello" testing::assert_eq
}
test "assert_ne checks inequality" {
5 6 testing::assert_ne
}
test "assert_true checks truthiness" {
1 testing::assert_true
42 testing::assert_true
"non-empty" testing::assert_true
}
test "assert_false checks falsiness" {
0 testing::assert_false
"" testing::assert_false
}
test "assert_approx_eq for floats" {
3.14159 3.14160 0.001 testing::assert_approx_eq
}
Running tests
Run all tests in a project
quad test
This discovers and runs all *_test.qd files and any files containing test blocks.
Run tests in a directory
quad test ./...
Run a specific test file
quad test math_test.qd
Using the compiler directly
quadc --test -r my_test.qd
Test file naming
By convention, test files are named *_test.qd and placed alongside the code they test:
mymodule/
mymodule.qd
mymodule_test.qd
Testing your own functions
use testing
fn factorial(n:i64 -- result:i64) {
-> n
n 1 <= if {
1
} else {
n n 1 - factorial *
}
}
test "factorial of 0 is 1" {
0 factorial 1 testing::assert_eq
}
test "factorial of 1 is 1" {
1 factorial 1 testing::assert_eq
}
test "factorial of 5 is 120" {
5 factorial 120 testing::assert_eq
}
Testing error handling
Test fallible functions by checking both success and failure cases:
use testing
fn divide(a:i64 b:i64 -- result:i64)! {
dup 0 == if {
drop2
"division by zero" -1 panic
}
/
}
test "divide succeeds with valid input" {
10 2 divide if {
5 testing::assert_eq
} else {
"should not fail" testing::fail
}
}
test "divide fails on zero" {
10 0 divide if {
"should not succeed" testing::fail
} else {
// Error case: division by zero was caught
1 testing::assert_true
}
}
Testing with modules
Import the module you're testing:
use testing
use str
test "str::len counts characters" {
"hello" str::len 5 testing::assert_eq
"" str::len 0 testing::assert_eq
}
test "str::contains finds substrings" {
"hello world" "world" str::contains testing::assert_true
"hello world" "xyz" str::contains testing::assert_false
}
Key concepts
test "name" { }- Defines a test block with a descriptive nameuse testing- Import the testing module for assertionsquad test- Run all tests in the project*_test.qd- Naming convention for test files- No
mainneeded - Test files don't require a main function
What's next?
Learn about Debugging techniques for finding and fixing issues.