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
#!ek9 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: assert, assertion, check, condition, precondition, require, test, throws, verify