A basic unit test framework for lune.
I developed this mostly for myself at a time where there were no alternatives for Lune. I plan to keep it simple and use it for my projects that dont require a heavy framework.
If you require more than basic test running, assertions, and console reporting, consider using a larger framework (like jest-lua when it gets ported to lune, see issue for tracking)
Here's what a test looks like:
return function()
test.suite("A collection of tests", function()
test.case("A test that passes", function()
local exp = 4
local got = 2 + 2
check.equal(got, exp)
end)
test.case("A test that fails", function()
local exp = 3
local got = 2 + 2
check.equal(got, exp)
end)
test.case("Halt early", function()
local a = nil
req.not_nil(a)
check.falsy(a.b) -- wont run, a failed req stops the test early
end)
test.case("Custom messages!", function()
check.equal(1, 2, msg("my message prints in addition to the expansion"))
end)
test.case("Array assertions", function()
local a = { "a", "b", "c" }
local b = { "a", "z" }
check.array.contains(a, { "z", "x" })
check.array.equal(a, b)
end)
test.case("Table assertions", function()
local a = { a = 1, b = 2, c = { a = 1, b = 2 } }
local b = { a = 1, b = 22, c = { a = -1 } }
check.table.contains(a, "b")
check.table.equal(a, b)
end)
end)
-- you can use test.focus to temporarily focus on a test case/suite:
test.focus.suite("only this suite will run", function() end)
test.focus.case("only this case will run", function() end)
-- you can use test.skip to skip test cases/suites:
test.skip.suite("all tests in this suite will be skipped", function() end)
test.skip.case("this test will be skipped", function() end)
end
And here is the output (theme is Rose Pine):
Installing
frktest is available on wally, pesde, or you can just clone the repo.
All example assume you created a require
alias "@frktest"
in your project's .luaurc
:
{
"aliases": {
"frktest": "<see install sections above for paths>",
}
}
note: you should also register the alias with your lsp of choice, with luau-lsp
using VSCode I think it would look like this:
"luau-lsp.require.mode": "relativeToFile",
"luau-lsp.require.directoryAliases": {
"@frktest/": "<alias in luaurc>"
}
The framework does not have a cli or test discovery. So you need to make an entrypoint file, see examples/_run.luau for how I made mine. But basically all you need is this:
-- filename: _run.luau
-- require test files and call the returned function
require("./some_test")()
-- initialize a reporter (there is currently only one... this one, but you can make your own!)
local lune_console_reporter = require("@frktest/reporters/lune_console_reporter")
lune_console_reporter.init()
-- run the tests
local frktest = require("@frktest/frktest")
frktest.run()
Then you can run this file with lune like so:
> lune run _run.luau
I suggest you use these requires (but you do what you want!):
local frktest = require("@frktest/frktest")
local test = frktest.test
local check = frktest.assert.check
local req = frktest.assert.require
A test file should return a function, and for any tests to run the function
needs to create tests with test.case
. If you want to group tests together you
can use test.suite
and create tests inside of that. See examples
for how I wrote a bunch of test files.
return function()
test.case("a global test", function()
-- ...
end)
test.suite("a group of tests", function()
test.case("a test within a suite", function()
-- ...
end)
end)
end
Every single assertion has at least one example in the examples folder. If there are any nuances, I added comments.
Really though, they should be self explanatory, your LSP should list them all
out if you type assert.check.|
table.equal
assertionsMy name is Frank, I often use frk
as a namespace/prefix for stuff meant for me :)