Configuring Jest
The Jest Lua philosophy is to work great by default, but sometimes you just need more configuration power.
The configuration should be defined in a jest.config.lua file.
The configuration file should simply export a table:
return {
verbose = true,
}
Or an async function returning an object:
return Promise.resolve():andThen(function()
return {
verbose = true,
}
end)
Options
clearmocks[boolean]displayName[string, table]projects[array<Instance>]rootDir[Instance]roots[array<Instance>]setupFiles[array<ModuleScript>]setupFilesAfterEnv[array<ModuleScript>]slowTestThreshold[number]snapshotFormat[table]snapshotSerializers[array<serializer>]testFailureExitCode[number]testMatch[array<string>]testPathIgnorePatterns[array<string>]testRegex[string | array<string>]testTimeout[number]verbose[boolean]
Reference
clearmocks [boolean]
Default: false
Automatically clear mock calls, instances, contexts and results before every test. Equivalent to calling jest.clearAllMocks() before each test. This does not remove any mock implementation that may have been provided.
displayName [string, table]
Default: nil
Allows for a label to be printed alongside a test while it is running. This becomes more useful in multi-project repositories where there can be many jest configuration files. This visually tells which project a test belongs to.
return {
displayName = 'CLIENT',
}
Alternatively, a table with the keys name and color can be passed. This allows for a custom configuration of the background color of the displayName. displayName defaults to white when its value is a string. Jest Lua uses chalk-lua to provide the color. As such, all of the valid options for colors supported by chalk-lua are also supported by Jest Lua.
return {
displayName = {
name = 'CLIENT',
color = 'blue',
}
}
projects [array<Instance>]
Default: nil
When the projects configuration is provided with an array of instances, Jest Lua will run tests in all of the specified projects at the same time. This is great for monorepos or when working on multiple projects at the same time.
return {
projects = { Workspace.ProjectB, Workspace.ProjectB },
}
This example configuration will run Jest Lua in the ProjectA as well as the ProjectB directories. You can have an unlimited amount of projects running in the same Jest Lua instance.
When using multi-project runner, it's recommended to add a displayName for each project. This will show the displayName of a project next to its tests.
rootDir [Instance]
Default: The root of the directory containing your Jest Lua config file.
The root directory that Jest Lua should scan for tests and modules within.
Oftentimes, you'll want to set this to your main workspace, corresponding to where in your repository the code is stored.
roots [array<Instance>]
Default: {<rootDir>}
A list of paths to directories that Jest Lua should use to search for files in.
There are times where you only want Jest Lua to search in a single sub-directory (such as cases where you have a src/ directory in your repo), but prevent it from accessing the rest of the repo.
setupFiles [array<ModuleScript>]
Default: {}
A list of ModuleScripts that run some code to configure or set up the testing environment. Each setupFile will be run once per test file. Since every test runs in its own environment, these scripts will be executed in the testing environment before executing setupFilesAfterEnv and before the test code itself.
setupFilesAfterEnv [array<ModuleScript>]
Default: {}
A list of ModuleScripts that run some code to configure or set up the testing framework before each test file in the suite is executed. Since setupFiles executes before the test framework is installed in the environment, this script file presents you the opportunity of running some code immediately after the test framework has been installed in the environment but before the test code itself.
In other words, setupFilesAfterEnv modules are meant for code which is repeating in each test file. Having the test framework installed makes Jest globals, jest object and expect accessible in the modules. For example, you can add extra matchers or call setup and teardown hooks:
local JestGlobals = require("@DevPackages/JestGlobals")
local jest = JestGlobals.jest
local expect = JestGlobals.expect
local afterEach = JestGlobals.afterEach
expect.extend({
newMatcher = function(self, received, expected)
-- ...
end)
})
afterEach(function()
jest.useRealTimers()
end)
return {
setupFilesAfterEnv = { Workspace.setupJest },
}
slowTestThreshold [number]
Default: 5
The number of seconds after which a test is considered as slow and reported as such in the results.
snapshotFormat [table]
Default: nil
Allows overriding specific snapshot formatting options documented in the pretty-format readme, with the exceptions of compareKeys and plugins.
pretty-format also supports the formatting option printInstanceDefaults (default: true) which can be set to false to only print properties of a Roblox Instance that have been changed.
For example, this config would have the snapshot formatter not print out any unmodified values of TextLabel.
return {
testMatch = { "**/*.spec" },
snapshotFormat = { printInstanceDefaults = false }
}
test('printInstanceDefaults', function()
local label = Instance.new("TextLabel")
label.Text = "Hello"
expect(label).toMatchSnapshot()
end)
exports[ [=[printInstanceDefaults 1]=] ] = [=[
TextLabel {
"Text": "Hello",
}
]=]
pretty-format further supports redacting stack traces from error logs via the
RedactStackTraces plugin. By default, this only attempts to redact the
contents of Error objects, but can be configured to search through strings
with the redactStackTracesInStrings boolean (default: false).
For example, this lets you save snapshots that contain stack traces, without those stack traces depending on the actual code structure of the repository. This reduces the chance of the snapshot test breaking due to unrelated changes in far-away parts of the code.
return {
testMatch = { "**/*.spec" },
snapshotFormat = { redactStackTracesInStrings = true }
}
test('print stack trace', function()
expect(debug.traceback()).toMatchSnapshot()
end)
exports[ [=[print stack trace 1]=] ] = [=[
Redacted.Stack.Trace:1337 function epicDuck
Redacted.Stack.Trace:1337 function epicDuck
Redacted.Stack.Trace:1337 function epicDuck
Redacted.Stack.Trace:1337 function epicDuck
]=]
snapshotSerializers [array<serializer>]
Default: {}
A list of snapshot serializers Jest Lua should use for snapshot testing.
Jest Lua has default serializers for built-in Lua types, Roblox types and Instances, and React Roblox elements.
local function serialize(val, config, indentation, depth, refs, printer)
return "Pretty foo: "
.. printer(val.foo, config, indentation, depth, refs, printer)
end
local function test(val)
return typeof(val) == "table" and val.foo ~= nil
end
return {
serialize = serialize,
test = test,
}
printer is a function that serializes a value using existing plugins.
Add customSerializer to your Jest Lua configuration:
return {
snapshotSerializers = { Workspace.customSerializer }
}
Finally tests would look as follows:
test('uses custom serializer', function()
local bar = {
foo = {
x = 1,
y = 2,
}
}
expect(bar).toMatchSnapshot()
end)
Rendered snapshot:
Pretty foo: Table {
"x": 1,
"y": 2,
}
To make a dependency explicit instead of implicit, you can call expect.addSnapshotSerializer to add a module for an individual test file instead of adding its path to snapshotSerializers in Jest configuration.
More about serializers API can be found here.
testFailureExitCode [number]
Default: 1
The exit code Jest Lua returns on test failure.
This does not change the exit code in the case of Jest Lua errors (e.g. invalid configuration).
testMatch [array<string>]
Default: { "**/__tests__/**/*", "**/?(*.)+(spec|test)" }
The glob patterns Jest Lua uses to detect test files.
By default it looks for .spec or .test files inside of __tests__ folders, as well as any files with a suffix of .test or .spec (e.g. Component.test.lua or Component.spec.lua). It will also find files called test.lua or spec.lua.
See the micromatch package for details of the patterns you can specify.
See also testRegex [string | array<string>], but note that you cannot specify both options.
Each glob pattern is applied in the order they are specified in the config. For example {"!**/__fixtures__/**", "**/__tests__/**/*.spec"} will not exclude __fixtures__ because the negation is overwritten with the second pattern. In order to make the negated glob work in this example it has to come after **/__tests__/**/*.spec.
testPathIgnorePatterns [array<string>]
Default: {}
An array of regexp pattern strings that are matched against all test paths before executing the test. If the test path matches any of the patterns, it will be skipped.
testRegex [string | array<string>]
Default: {}
The pattern or patterns Jest Lua uses to detect test files. See also testMatch [array<string>], but note that you cannot specify both options.
testRegex will try to detect test files using the absolute file path, therefore, having a folder with a name that matches it will run all the files as tests.
testTimeout [number]
Default: 5000
Default timeout of a test in milliseconds.
verbose [boolean]
Default: false
Indicates whether each individual test should be reported during the run. All errors will also still be shown on the bottom after execution. Note that if there is only one test file being run it will default to true.