unitt

Unitt is a basic unit-test tool for the Arturo Programming language.

unit tests

Unitt

Unitt is a lean unit-test tool for the Arturo Programming language

Arturo logo Arturo logo

At a Glance

Running Unitt from terminal

Trying Unitt

Unitt may be splited into two sections: runner and the tests.

The runner is the section responsible to find, run and return error codes to the final user. While the tests are responsible to group the rules and logic of the tests.

Initial setup

It's recomended that your tester be at the root of your directory, right before your tests folder.

All of your tests must begin with the test prefix and end with the .art extension to be found, since you may want to mix them with some other files.

Being that said, that is the right way of setting up your tester:

Let's consider that you have the following directory:

src/
    ...
tests/
    ...
main.art
tester.art

Into your tester.art, you must:

import {unitt}!

runTests findTests "tests"

To run it, call:

arturo tester.art

Tip
You may want to use a hashbang to don't need to call arturo for every run.

Tip
If you want be able to test some specific tests from the CLI, you can:

 import {unitt}!
 
 runTests (empty? arg)? 
     -> findTests "tests"
     -> arg

The tests itself

A real example of tests:

import {unitt}!

unix?: true

suite "test binary appending" [
    test "operation with integer works" [
        b: to :binary 0
        assert -> as.binary 2 = append b 1
        assert -> as.binary 1 = b ++ 1
    ]

    test.prop "operate binaries with integer returns a binary" [
        b: to :binary 0
        assert -> binary? append b 1
        assert -> binary? b ++ 1
    ]
]

test.skip: unix? "split works for windows's paths" [
    assert -> ["." "splited" "path"] = split.path ".\\splited\\path"
]

test "split is works for unix path" [
    assert -> ["." "splited" "path"] = split.path "./splited/path"
]

This will show you:

Suite: test binary appending 

    ❌ - assert that operation with integer works
         assertion: as .binary 2 = append  1

    ❌ - assert that operation with integer works
         assertion: as .binary 1 =  ++ 1

    ✅ ~ assert that operate binaries with integer returns a binary
         assertion: binary? append  1

    ✅ ~ assert that operate binaries with integer returns a binary
         assertion: binary?  ++ 1


⏩ - assert that split works for windows's paths 
     skipped!

✅ - assert that split is works for unix path
     assertion: ["." "splited" "path"] = split .path "./splited/path"

Note
Property-based tests have ~ as separator.

The Runner

Basically, you can run your tests units without a runner. But there are some reasons why you should prefer to use a runTests function to run them.

First, your runner's output will give you important information about the current run. This will show you the file being runned, the tests's status and at the end a summary of failed, skipped and passed tests:

===== Statistics =====

⏏️   TOTAL: 24 assertions
✅  PASSED: 20 assertions
⏩ SKIPPED: 4 assertions
❌  FAILED: 4 assertions

===== ========== =====

Also, the runner is able to return an error code, so that is great if you're working with Continuous Integration.

Documentation

Runner

  • runTests: $[tests [:string]]: The runner function, this executes all tests, show statistics and return a value.
    • .failFast: Fails on the first error found. This works at file scope due to our current way of running tests.
    • .suppress: Suppress panic, this means: this won't terminate your tests, won't return an error code and won't print a panic message.
  • findTests: $[folder :string]: The finder function, this function will look for tests inside the relative folder. The default test pattern is "test*.art".
    • .thatMatches :string: Defines what is a test-file via a kind-of glob pattern. Use a * as spliter.
      • Obs.: That is a kind-of glob pattern, not a real one. So just use one and only one * to split the pre and suffix.

Tests

  • test: $[description :string, testCase :block]: The test case itself, you need to pass a clear description to it, And the logic that you're trying to assert.
    • .prop: Indicates that a test is property-based.
    • .skip :logical: Skips tests for some condition. If none condition is given, this will just skip the test.
    • .static: :block: Defines what will and what won't be evaluated.
    • .static: :logical: Disable runtime evaluation, and forces static display.
  • assert: $[condition :block]: A function that is only available inside the test case, makes an assertion given the condition.
  • suite: $[description :string tests :block]: Visually groups tests together.

Warning
Never import this lib as .lean, or this will break the current code. This happens due to the nature of Arturo (being concatenative), and the way we importings are working right now. This may change in future.


Background photo on "At a Glance" by Jack Anstey on Unsplash

  -
  
  2
Version
1.1.2Latest
License
MIT

Executable?
No
Requires
Arturo > 0.9.83