Configuring Jest
The Jest Roblox 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 Roblox 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 Roblox.
return {
displayName = {
name = 'CLIENT',
color = 'blue',
}
}
projects
[array<Instance>]
Default: nil
When the projects
configuration is provided with an array of instances, Jest Roblox 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 Roblox in the ProjectA
as well as the ProjectB
directories. You can have an unlimited amount of projects running in the same Jest Roblox 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 Roblox config file.
The root directory that Jest Roblox 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 Roblox should use to search for files in.
There are times where you only want Jest Roblox 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(Packages.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 Roblox should use for snapshot testing.
Jest Roblox 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 Roblox 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 Roblox returns on test failure.
This does not change the exit code in the case of Jest Roblox errors (e.g. invalid configuration).
testMatch
[array<string>]
Default: { "**/__tests__/**/*", "**/?(*.)+(spec|test)" }
The glob patterns Jest Roblox 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 Roblox 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
.