Unit testing

Inko's standard library provides a module used for writing unit tests: std.test. Using this module one writes their unit tests like so:

import std.test (Tests)

fn pub tests(t: mut Tests) {
  t.test('The name of the test', fn (t) {
    t.equal(10, 20)
  })
}

Each test can specify one or more expectations to check. If an expectation fails, the failure is recorded and the test continues running. Not aborting the test upon the first failure makes it easier to measure progress and makes the testing process less frustrating, as you aren't shown only the first failure per test.

Tests are run in a randomised order, and concurrently. By default the number of concurrent tests equals the number of available CPU cores, but this can be changed if necessary.

For more information about the testing API, take a look at the source code of the std.test module.

In the future Inko will support generating source code documentation, at which point looking at the source code is no longer necessary.

Testing structure

Test files follow the naming convention of test_X.inko, where X is the name of the module tested. Tests are to be placed in a directory called test and mirror the module hierarchy of the module they are testing. For example, the tests for the standard library are organised as follows:

std/test/
└── std
    ├── fs
    │   ├── test_dir.inko
    │   ├── test_file.inko
    │   └── test_path.inko
    ├── net
    │   ├── test_ip.inko
    │   └── test_socket.inko
    ├── test_array.inko
    ├── test_bool.inko
    ├── ...
    └── test_tuple.inko

Running tests

With these files in place you can run your tests using inko test. When doing so, make sure your current working directory is the directory containing the test directory, otherwise Inko won't find your unit tests.

The inko test command supports filtering tests by their name. For example, to run tests of which the name contains "kittens" you'd run the tests like so:

inko test kittens

You can also filter by a file path, only running the tests in that file:

inko test test_kittens.inko

Testing private types and methods

Following the structure outlined above, you're able to test private types and methods, as tests and the modules they are testing both exist in the same root namespace. That is, tests for std.foo would be located in the module std.test_foo, and thus have access to private types and methods defined in any module under the std root namespace. This in turn removes the need to mark types or methods as public just so you can test them.