How do I assert conditions in a test in EK9?
← Testing · Ref: Q156
EK9 provides assert for test assertions and require for production preconditions. Both are built-in keywords, not library functions.
ASSERT KEYWORD
Use assert in test programs to verify conditions:
assert result == 5 assert name? assert items.length() > 0
Assert is only allowed in test context (programs marked with @Test). It throws an exception if the condition is false.
REQUIRE FOR PRECONDITIONS
Use require in production code for preconditions:
require name? require age > 0
Require works in any context and enforces that callers provide valid inputs.
ASSERT VS REQUIRE
assert is for test verification: 'did the code produce the right result?'
require is for defensive programming: 'are the inputs valid before proceeding?'
Assert is restricted to test programs. Require works everywhere.
OUTPUT-BASED TESTING AS ALTERNATIVE
For cleaner tests, print values to stdout and compare against expected_output.txt files. This avoids assert bytecode contamination in @BYTECODE directives and provides two independent validations: output verifies runtime behavior, directives verify code generation.
See Q155 for writing tests. See Q134 for try/catch. See Q135 for throwing exceptions. See Q204 for black-box testing. See Q209 for exception testing.
See Q305 for require vs assert vs throw. See Q306 for assertThrows. See Q307 for assertDoesNotThrow.
Example
defines module qa.testing.assertions defines function add() as pure -> a as Integer b as Integer <- rtn as Integer: a + b isPositive() as pure -> number as Integer <- rtn as Boolean: number > 0 defines program // === ASSERT IN TESTS === @Test BasicAssertTest() stdout <- Stdout() result <- add(2, 3) assert result == 5 assert isPositive(42) name <- "EK9" assert name? stdout.println("All assertions passed") // === REQUIRE FOR PRECONDITIONS === @Test RequireTest() stdout <- Stdout() count <- 10 require count > 0 text <- "Hello" require text? assert count == 10 assert text == "Hello" stdout.println("All preconditions met") // === OUTPUT-BASED ALTERNATIVE === @Test OutputBasedTest() stdout <- Stdout() // Print values and compare against expected_output.txt result <- add(10, 20) assert result == 30 stdout.println("Result: " + $result)
Common mistakes
E07530 — The assert keyword requires a Boolean expression. Passing an Integer or String directly triggers E07530 — only compatible with Boolean type. Use a comparison operator to produce a Boolean. See ek9 -h E07530 for details.
Incorrect:
assert result
Correct:
assert result == 5
E50060 — Integer has no toString() method. Use the $ prefix operator for string conversion or string interpolation. See ek9 -h E50060 for details.
Incorrect:
stdout.println(result.toString())
Correct:
stdout.println("All assertions passed")
E50060 — Integer has no valueOf() method. Use the $ prefix operator or string concatenation with + for string conversion. See ek9 -h E50060 for details.
Incorrect:
stdout.println(result.valueOf())
Correct:
stdout.println("Result: " + $result)
Other ways to ask this
- What assertion keywords does EK9 have?
- How do I use assert and require in EK9?
- What is the difference between assert and require in EK9?
Coming from another language?
Java: assertEquals/assertTrue from JUnit, assertThrows for exceptions. Python: assert statement or pytest.raises for exceptions. Rust: assert!, assert_eq!, assert_ne! macros. Go: t.Error() and t.Fatal() on testing.T. EK9: built-in assert keyword for tests, require keyword for preconditions, plus output-based testing as a cleaner alternative.
Keywords: require, test, verify, check, condition, assert, precondition, throws, assertion