test
A collection of utilities for writing tests.
Writing tests
To add tests to a Koto script, export a Map named @tests, and then any
functions in the Map tagged with @test will be run as tests.
If a function named @pre_test is in the @tests Map, then it will be run
before each test. Similarly, if a function named @post_test is present then it
will be run after each test.
These functions are useful if some setup work is needed before each test, and then maybe there's some cleanup work to do after the test has finished.
To access the result of the setup work, if the test function takes self as its
first argument, then the @tests Map itself will be passed in as self.
Example
# Tests are exported from a module as a map named `@tests`
export @tests =
# '@pre_test' will be run before each test
@pre_test: |self|
self.test_data = 1, 2, 3
# '@post_test' will be run after each test
@post_test: |self|
self.test_data = ()
# Functions that are tagged with @test are automatically run as tests
@test basic_assertions: ||
# assert checks that its argument is true
assert 1 > 0
# assert_near checks that its arguments are equal, within a specied margin
allowed_error = 0.1
assert_near 1.3, 1.301, allowed_error
# Instance test functions receive the tests map as `self`
@test data_size: |self|
# assert_eq checks that its two arguments are equal
assert_eq self.test_data.size(), 3
# assert_ne checks that its two arguments are not equal
assert_ne self.test_data.size(), 1
Running tests
Enabling tests in the runtime
When the Koto runtime has the run_tests setting enabled, then after a module
is compiled and initialized then tests will be run before calling the main
function.
Enabling tests in the CLI
The run_tests setting can be enabled when using the koto CLI with
the --tests flag.
Running tests from a Koto script
Tests can be run from a Koto script by calling test.run_tests.
Reference
assert
|Bool| -> ()
Throws a runtime error if the argument if false.
Example
# This assertion will pass, and no error will be thrown
assert 1 < 2
# This assertion will fail and throw an error
assert 1 > 2
# error: Assertion failed
assert_eq
|Value, Value| -> ()
Checks the two input values for equality and throws an error if they're not equal.
Example
# This assertion will pass, and no error will be thrown
assert_eq 1 + 1, 2
# This assertion will fail and throw an error
assert_eq 2 + 2, 5
# error: Assertion failed, '4' is not equal to '5'
assert_ne
|Value, Value| -> ()
Checks the two input values for inequality and throws an error if they're equal.
Example
# This assertion will pass, and no error will be thrown
assert_ne 1 + 1, 3
# This assertion will fail and throw an error
assert_ne 2 + 2, 4
# error: Assertion failed, '4' should not be equal to '4'
assert_near
|Number, Number, Number| -> ()
|Num2, Num2, Number| -> ()
|Num4, Num4, Number| -> ()
Checks that the two input numbers are equal, within an allowed margin of error.
This is useful when testing floating-point operations, where the result can be close to a target with some acceptable imprecision.
Example
allowed_error = 0.01
# This assertion will pass, and no error will be thrown
assert_near 1.3, 1.301, allowed_error
# This assertion will fail and throw an error
assert_near 1.3, 1.32, allowed_error
# error: Assertion failed, '1.3' and '1.32' are not within 0.01 of each other
run_tests
|Map| -> ()
Runs the tests contained in the map.
Example
my_tests =
@pre_test: |self| self.test_data = 1, 2, 3
@post_test: |self| self.test_data = ()
@test data_size: |self| assert_eq self.test_data.size(), 3
@test failure: |self| assert not self.test_data.is_empty()
try
run_tests my_tests
catch error
print "An error occurred while running my_tests: {}", error