Skip to main content


To write unit tests for Rell code, use test module. You need to use the @test annotation to define a test module:

@test module;

function test_foo() {
assert_equals(2 + 2, 4);

function test_bar() {
assert_equals(2 + 2, 5);

All functions in a test module that start with test_ (and a function called exactly test) are test functions that're executed when you run the test module.

If the module has the "_test" suffix, it becomes a test module for the module that bears the same name without the suffix. For example, if the module name is program, the test module is program_test

Tests get executed using a postchain node with the following signer key:

val signer_privkey = x"4242424242424242424242424242424242424242424242424242424242424242";
val signer_pubkey = x"0324653EAC434488002CC06BBFB7F10FE18991E35F9FE4302DBEA6D2353DC0AB1C";

To run a test module, use the test command (chr test):

chr test --settings chromia.yml --modules my_test_module

For more information, see the chr test topic. Each test function gets executed independently of others, and a summary gets printed at the end:


my_test_module:test_foo OK
my_test_module:test_bar FAILED


***** FAILED *****

Transactions in a test module

Instead of writing tests in a frontend, we write the transactions in Rell like this:

  • rell.test.block - a block. It contains a list of transactions.

  • rell.test.tx - a transaction. It has a list of operations and a list of signers.

  • rell.test.op - an operation call, which is a (mount) name and a list of arguments (each argument is a gtv).

You can create the keys for signing transactions as follows:

  • rell.test.keypairs.{bob, alice, trudy, charlie, dave, eve, frank, grace, heidi}: rell.test.keypair - test keypairs
  • rell.test.privkeys.{bob, alice, trudy, charlie, dave, eve, frank, grace, heidi}: byte_array - same as rell.test.keypairs.X.priv
  • rell.test.pubkeys.{bob, alice, trudy, charlie, dave, eve, frank, grace, heidi}: byte_array - same as

Example of an operation signed with the alice keypair:

  • rell.test.tx().op(main.exampleOp(parameter1,parameter2)).sign(rell.test.keypairs.alice).run();

    And if nop is necessary for making a transaction unique, one can use rell.test.nop() to implement it.

  • rell.test.nop(x: integer): rell.test.op > rell.test.nop(x: text): rell.test.op > rell.test.nop(x: byte_array): rell.test.op creates a nop operation with a specific argument value.