Unit Test Library
#Quick setup guide

The following setup guide will assume that you have created your project within MicroMacro's script directory; for example, C:/micromacro/scripts/my-project

First things first, you will need to create a new directory named tests in your project's root directory. Within the tests directory, you can create any many files and subdirectories as you need. By default, any file under tests with the .lua extension will be checked for tests functions. Any found function that has a name that begins with test_ will be considered a unit test function.

Your project directory might look something like this:


Now that our project structure is set up, we can begin writing unit tests in tests/test_utils.lua, or any other file underneath tests if we wish.

function test_my_first_unit_test() assert(true) end

Finally, we can run our unit tests by entering the command when prompted:

test my-project

If everything went according to plan, we should see that our unit test function was run and passed all checks:

Running tests
 [PASS]  test_utils.lua::test_my_first_unit_test ............... 0.00ms

Tests: 1, Assertions: 1, Passed: 1, Failed: 0

A few things to remember:

  • You must place your unit test files in a directory named tests in your project root.
  • You should name your test files with the .lua extension to ensure they are checked by default.
  • Your test files, other than extension, can be named anything you would like, but it is generally good practice to name them starting with test_ and follow with a useful description, indicating what functionalities it tests.
  • You may create additional subdirectories under tests to organize your test files.
  • Your test files may have many test functions within them.
  • Your test files may also have non-test functions; any function that has a name that does not begin with test_
  • Each test function should have one or more assertion. See writing unit tests for more details.
  • While you may have multiple assertions in your test functions, each test function should test only one principal (ie. test the unit).

#Writing unit tests

Inside each test function, you should have one or more assertion. These can be as simple as making use of Lua's built-in assert() function, or using a variety of MicroMacro's available assertions.

To make use of MicroMacro's assertions, your test function should accept an instance of the Assert class and call one of the available assertions on it. See below for examples.

expectError(closure)Runs the given closure and generates an error if the closure succeeded (did not result in error). You should use this to validate that some piece of code does throw an error.
same(left, right)Tests that two values are the same. Throws an error if `left` and `right` are not the same type and value.
different(left, right)Tests that two values are different. Throws an error if `left` and `right` are the same type and value.
contains(haystack, needle)Tests that a table does contain a value. Throws an error if table `haystack` does not contain `needle`.
notContains(haystack, needle)Tests that a table does not contain a value. Throws an error if table `haystack` does contain `needle`.
Example usage
function addition(a, b) return a + b end function test_basic_assert() assert(true); -- Lua's built-in assert method, passes if the argument is neither `nil` nor `false` assert(addition(2, 3) == 5) end function test_expects_error_assertion(asserter) asserter:expectError(function () addition("hello", "world") -- should cause an error since we cannot add strings, causing the assertion to pass end) end function test_example_of_same_assertion(asserter) asserter:same(12, 12) -- passes asserter:same(12, 12.0) -- passes asserter:same("hello", "hello") -- passes asserter:same(1, 15) -- fails asserter:same("hello", "Hello") -- fails end function test_example_of_different_assertion(asserter) -- Basically just the opposite of `same`... asserter:different(123, "hello") end function test_example_of_contains_assertion(asserter) local tab = {1, 2, 3, 4, 5} asserter:contains(tab, 3) -- passes asserter:contains(tab, 7) -- fails end function test_example_of_not_contains_assertion(asserter) local tab = {1, 2, 3, 4, 5} asserter:notContains(tab, 3) -- fails asserter:notContains(tab, 7) -- passes end
#Running unit tests

Unit tests can be run by invoking the test command and passing the root directory to your project as the first argument. For example, if your project directory is named my-project and resides in MicroMacro's scripts directory, you may use test my-project.

You may also provide some additional options to this command. --verbose may be used to provide more detailed output (if available), and --filter-files may be used to override which file(s) to scan for.

--filter-files usage example
test my-project --filter-files=.*%.txt,.*%.lua # Runs tests in any files under tests/ dir that ends with .txt or .lua test my-project --filter-files=doc.lua # Only runs tests inside tests/doc.lua

Page last updated at 2024-04-12 17:26:48

Copyright 2024