Lunity
Lunity copied to clipboard
Simple-but-rich unit testing for Lua
Lunity v0.12
A simple single-file unit test system for Lua with a somewhat rich set of assertions and custom error messages. Features:
- Lua 5.2,5.3 compatible.
- Framework is a single file.
- Control the order that tests are run (by renaming functions).
- Can output ANSI (for conforming terminals) or HTML (for TextMate or e).
- Sensible (to me) injection of functions while preserving global scope.
- Rich set of assertions and custom error messages.
(Including assertion for comparing tables of values.)
Simplest Usage
-- This magic line makes a `test` table available,
-- and makes all the assertions available to your tests
_ENV = require('lunity')()
-- Define tests that you want to run inside the `test` table
function test.simplest_assertion()
assert(true, "If true isn't true, we are in big trouble.")
end
-- At the end of your file, call `test()` to run the tests
test()
Robust Usage
-- You can optionally give a name to your test suite
_ENV = require('lunity')('check robustness')
function test:before()
-- code here will be run before each test
-- `self` is available to store information needed for the test
end
function test:after()
-- run after each test, in case teardown is needed
end
-- Tests can have any name (other than 'before' or 'after')
-- The `self` table is the same scratchpad available to before()
function test:foo()
assertTrue(42 == 40 + 2)
assertFalse(42 == 40)
assertEqual(42, 40 + 2)
assertNotEqual(42, 40, "These better not be the same!")
assertTableEquals({ a=42 }, { ["a"]=6*7 })
-- See below for more assertions available
end
-- You can define helper functions for your tests to call with impunity
local function some_utility()
return "excellent"
end
-- Tests will be run in alphabetical order of the entire function name
-- However, relying on the order of tests is an anti-pattern; don't do it
function test:bar()
assertType(some_utility(), "string")
end
local allPassed = test{
useANSI=false, -- turn off ANSI codes (colors/bold) in the output
useHTML=true, -- turn on HTML markup in the output
quiet=true, -- silence print() and io.write() other than Lua during the tests
}
if not allPassed then os.exit(1) end
Assertions Available
The msg parameter is always optional; effort has been made to provide a helpful message if none is provided.
fail(msg)- instantly fail the testassert(testCondition, msg)- fail iftestConditionis eithernilorfalseassertEqual(actual, expected, msg)- fail ifactual ~= expectedassertNotEqual(actual, expected, msg)- fail ifactual == expectedassertTableEquals(actual, expected, msg)- recursively compare two tables and fail if they have any different keys or valuesassertTrue(actual, msg)- fail ifactual ~= trueassertFalse(actual, msg)- fail ifactual ~= falseassertNil(actual, msg)- fail ifactual ~= nilassertNotNil(actual, msg)- fail ifactual == nilassertType(actual, expectedType, msg)- fail iftype(actual) ~= expectedType, e.g.assertType(getResults(),"table","getResults() needs to return a table")assertTableEmpty(actual, msg)- fail ifactualis not a table, or ifactualis a table with any keys (including a key with the value offalse)assertTableNotEmpty(actual, msg)- fail ifactualis not a table, or ifactualdoes not have any keysassertSameKeys(table1, table2, msg)- fail if either table has a key not present in the other (good for set comparisons)assertInvokable(value, msg)- fail ifactualis not a function, or may not be invoked as one (viameta.__call)assertErrors(invokable, ...)- call the functioninvokablepassing along extra parameters, and fail if no errors are raisedassertDoesNotError(invokable, ...)- call the functioninvokablepassing along extra parameters, and fail if any errors are raised
Helper Functions
The following functions are made available to your tests, though they do not count as assertions and will not cause a test failure on their own.
is_nil(value)- return true ifvalueisnilis_boolean(value)- return true ifvalueis a booleanis_number(value)- return true ifvalueis a numberis_string(value)- return true ifvalueis a stringis_table(value)- return true ifvalueis a tableis_function(value)- return true ifvalueis a functionis_thread(value)- return true ifvalueis a threadis_userdata(value)- return true ifvalueis a userdata value
Note that while writing assert(is_table(value)) looks nicer in code than assertType(value, 'table'), the latter provides a better default error message to the user.
License
This work is licensed under the Creative Commons Attribution 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ or send a letter to
Creative Commons
171 Second Street, Suite 300
San Francisco, California, 94105, USA
Modification, reuse and redistribution permitted provided the following attribution and copyright line is included:
Copyright (c) 2012-2020 by Gavin Kistner (Phrogz)