lubyk logo

Lubyk documentation

Test Suite

The test suite is used to declare tests and group them by class or module.

.new (name, options)

Create a new test suite. It is good practice to use 'should' as local name for this suite since it makes tests more readable. The name should be the exact name of the class or module being tested in case the coverage option is activated in test (it is on by default).

Full test file example:

local lub    = require 'lub'
local lut    = require 'lut'
local should = lut.Test 'animal.Dog'

function should.bark()
  local medor = animal.Dog('Medor')
  assertEqual('Wouaf!', medor:bark())
end

-- Test files must end with this line
should:test()

The optional options table can contain the following keys to alter testing behavior:

coverage if set to false, untested functions will not be reported. If lut.Test.mock contains a string, this will be used as the body of missing tests and outputed.
metatablethe metatable for the class being tested if it cannot be found in global namespace.

In a test file, you can ignore coverage warning for deprecated functions by setting should.ignore.[func_name] = true.

:testWithUser ()

Return tests to only run in single mode (not in batch) because they require user interaction. Usage:

local should   = lut.Test 'lub.Dir'
local withUser = should:testWithUser()

function withUser.should.displayTable()
end

Command line arguments

When running tests from the command line, arguments are parsed by lut.Test for --verbose flag and --only=someTestName.

Example:

> lua test/all.lua --only=someTest --verbose

Global settings

Set these before running tests:

lut.Test.verbose = true
lut.Test.files(lub.path '|')

.TIMEOUT = 5

Default timeout value for timeout function.

.only = false

To only test a single method.

.verbose = false

Set to true to enable verbose mode (display each test title).

.abort = false

Abort batch mode (can be set in a test).

.mock = false

Untested functions are listed. If mock contains a string, it is used as body to generate mockups of untested functions.

Setup, teardown

If you need to run some code before or after every test, you can define the setup (executed before each test) and/or teardown (executed after each test independantly of success or failure) functions:

local should = lut.Test 'lub.Dir'

function should.teardown()
  -- cleanup
end

.setup ()

Dummy setup function (does nothing).

.teardown ()

Dummy teardown function (does nothing).

Declare tests

:__newindex (key, value)

Tests are declared by adding functions to the test suite. Note that these functions do not have access to 'self'.

Example test declaration:

functions should.beHappy()
  assertTrue(true)
end

Run tests

Use should:test() to run the tests in all suites at once. You can append this call at the end of the file to run the test when running the file:

function should.testLast()
end

-- Run all tests now.
should:test()

WARN Once tests are run, this function calls os.exit with a return code of 0 (success) or -1 (failure).

Batch testing

.files (list_or_path, pattern, reject)

Test all files in list_or_path matching pattern. Typical usage is to create an all.lua file in the tests folder with:

local lub = require 'lub'
local lut = require 'lut'
lut.Test.files(lub.path '|')

This will run tests for all files matching the default pattern %_test.lua$. If the optional reject pattern is provided, paths matching this pattern will be, well, rejected. See lub.path for details on the pipe syntax.

WARN Once tests are run, this function calls os.exit with a return code of 0 (success) or -1 (failure).

Assertions

fail (msg)

Force a test to fail with a given msg.

assertFalse (val)

Assert that val is false.

assertTrue (ok, msg)

Assert that ok is true. If msg exists, it is used in case of failure in place of the default fail message.

assertEqual (expected, value, resolution, up_count)

Assert that value is equal to expected. If expected is a number, the resolution parameter can be used to cope with numerical errors. The actual test for numbers is:

local ok = (value >= expected - resolution) and (value <= expected + resolution)

For other types, this tests raw equality (same object). To compare table contents, use assertValueEqual.

assertValueEqual (expected, value, resolution, up_count)

For tables, recursively test that all keys contain the same values.

assertTableEqual (expected, value, resolution, up_count)

This is like assertValueEqual but does not check for table type.

assertNotEqual (unexpected, value)

Asserts that value is not equal to unexpected.

assertMatch (pattern, value)

Assert that value matches pattern using string.match.

assertNotMatch (pattern, value, msg)

Assert that value does not match pattern. If msg is provided, use this in case of failure.

assertError (pattern, func)

Assert that calling func generates an error message that matches pattern.

assertPass (func, teardown)

Assert that calling func passes without errors. The optional teardown function can be used to cleanup after the function call whether it passes or fails.

assertLessThen (expected, value)

Assert that value is less then expected.

assertType (expected, value)

Assert that the Lua type of value is expected ('number', 'table', 'function', etc).

assertNil (value)

Assert that value is nil.

assertInRange (t1, t2, value)

Assert that value is in the range defined by [t1, t2[.

assertPassWithTimeout (func, msg, timeout)

Execute func every 0.3 s for timeout seconds or until the callback function returns true. The callback is passed the elapsed time as parameter. If no timeout value is passed, the default TIMEOUT is used (5 seconds).

If the timeout is reached, an error with msg (or a default text) is displayed.

function should.browseNetwork()
  local found_remote = false
  -- ...
  assertPassWithTimeout(function()
    return found_remote
  end, 'Could not find remote device')
end