LazyVim + neotest-mocha and overcoming `No test found`

I began to have issues with AstoVim setup and decided to slim down and build a LazyVim config to cover my needs. I will admit that debugging NeoVim and Lua is still a bit difficult for me to grok. I read a lot of bug reports and reached out to some people but I believe I got my answers.
So I installed LazyVim and fired up :Mason
and installed the following:
- bash-language-server
- eslint_d
- gitui
- js-debug-adapter
- lua-language-server
- marksman
- prettierd
- shellcheck
- shfmt
- sqlfluff
- stylua
- typescript-language-server
- vtsls
I went into Lazy Extras (just open nvim and hit x on the menu) and loaded
- dap.core
- dap.nlua
- editor.inc-rename
- editor.neo-tree
- formatting.prettier
- linting.eslint
- lsp.none-ls
- test.core
- util.gitui
- vscode
Finally I add the following config file ~/.config/nvim/lua/plugins/neotest
return {
"nvim-neotest/neotest",
dependencies = {
"nvim-neotest/nvim-nio",
"nvim-lua/plenary.nvim",
"antoinemadec/FixCursorHold.nvim",
"nvim-treesitter/nvim-treesitter",
"adrigzr/neotest-mocha",
},
opts = {
adapters = {
["neotest-mocha"] = {
log_level = vim.log.levels.DEBUG,
command = "npx mocha --",
command_args = function(context)
-- The context contains:
-- results_path: The file that json results are written to
-- test_name_pattern: The generated pattern for the test
-- path: The path to the test file
--
-- It should return a string array of arguments
--
-- Not specifying 'command_args' will use the defaults below
local relative_path = vim.fn.fnamemodify(context.path, ":.")
return {
"--full-trace",
"--reporter=json",
"--reporter-options=output=" .. context.results_path,
"--grep=" .. context.test_name_pattern,
relative_path,
}
end,
env = { CI = true },
cwd = function()
return vim.fn.getcwd()
end,
},
},
-- consumers = {
-- overseer = require("neotest.consumers.overseer"),
-- },
config = function(_, opts)
local neotest_ns = vim.api.nvim_create_namespace("neotest")
vim.diagnostic.config({
virtual_text = {
format = function(diagnostic)
-- Replace newline and tab characters with space for more compact diagnostics
local message = diagnostic.message:gsub("\n", " "):gsub("\t", " "):gsub("%s+", " "):gsub("^%s+", "")
return message
end,
},
}, neotest_ns)
if opts.adapters then
local adapters = {}
for name, config in pairs(opts.adapters or {}) do
if type(name) == "number" then
if type(config) == "string" then
config = require(config)
end
adapters[#adapters + 1] = config
elseif config ~= false then
local adapter = require(name)
if type(config) == "table" and not vim.tbl_isempty(config) then
local meta = getmetatable(adapter)
if adapter.setup then
adapter.setup(config)
elseif adapter.adapter then
adapter.adapter(config)
adapter = adapter.adapter
elseif meta and meta.__call then
adapter = adapter(config)
else
error("Adapter " .. name .. " does not support setup")
end
end
adapters[#adapters + 1] = adapter
end
end
opts.adapters = adapters
end
require("neotest").setup(opts)
end,
},
}
:q
The last step is in your project to setup .mocharc.json
file
Now some mocha project would error on No tests found
and it took me some time to figure out why because it isn't obvious. Neotest looks for files that match its discovery regex (*_test.js
, *.spec.js
, *.test.js
, …). If your files are named differently, they won’t be picked up.
You can override file discovery in the opt section
opts = {
adapters = {
["neotest-mocha"] = {
-- existing keys …
-- Add a custom pattern (Lua pattern, not glob):
discover_files = function(path)
return vim.fn.globpath(path, "**/*_spec.js", false, true) -- adjust as needed
end,
},
},
}
I hope this helps with anyone that encounters No tests found
with neotest.