Testing
Write and run tests.
On this page
Tests are test blocks next to your code. A build with --test runs them instead of main; normal builds leave them out. For other build options see Command line.
Write a test#
fn line_total(price: int, quantity: int) int {
return price * quantity
}
test "Line total uses the requested quantity" {
assert(line_total(12, 3) == 36)
assert(line_total(12, 0) == 0)
}
assert records a check. Every executed assert counts in the summary, so in a long loop collect the result in a variable and assert once after it.
Run tests#
valk build src --test --run
valk build src tests --test --run # tests in their own directory
valk build src tests --test --filter "Line total" --run
valk build src tests --test -o test-bin # build once
./test-bin --filter "Line total" # pick tests without rebuilding
--filter keeps only tests whose name contains the text. A failed comparison shows both sides and where it is:
#1 [code] assert(user.name == "Ada")
#1 [left] "ada"
#1 [right] "Ada"
#1 [file] tests/users.valk:12
The test program exits with a non-zero status when a test fails, so CI can run it directly.
Isolate tests that change shared state#
Regular tests run at the same time. Use synctest for a test that changes globals, environment variables or other process-wide state:
global counter: int (0)
synctest "Reset shared test state" {
counter = 0
counter++
assert(counter == 1)
}
All regular tests finish before synctests start; synctests then run one at a time in declaration order. A test can still start its own coroutines to check concurrent code.
Test errors#
error ParseError (empty)
fn parse_name(text: String) String !ParseError {
if text == "" : throw .empty
return text
}
test "Empty names are rejected" {
let failed = parse_name("") ! {
assert(E.code == E.empty)
return
}
assert(false)
}
Test helpers and platforms#
#if TEST
fn sample_users() Array[String] {
return Array[String]{ "ada", "bob" }
}
#end
test "Paths use the platform separator" {
#if OS == "win"
assert("a\\b".contains("\\"))
#else
assert("a/b".contains("/"))
#end
assert(sample_users().length == 2)
}
TEST is true in test builds, so helpers inside #if TEST are not part of the release. OS and ARCH select code per platform; see Compile-time code. To check that code builds for another platform, lint for that target as shown in Cross compiling.

