Google Test adapter for nvim-neotest
neotest-gtest
This is a [neotest] adapter for [Google Test][google-test], a popular C++ testing library. It allows easy interactions with tests from your neovim. It should work well out-of-the-box for most cases, though some features (see below) are not yet supported.
Requirements
- Neovim 0.9.1+, 0.10.x, or nightly.
- [Google Test][google-test] 1.10+
- [neotest] (latest, incl. nvim-nio and plenary.nvim)
- [nvim-treesitter] (latest, with CPP parser installed via
TSInstall cpp) - [nvim-dap] (latest, optional, required for debugging)
Features
The plugin provides full support of all neotest features:
- running tests inside NeoVim
- seeing pretty output
- debugging tests
- all other niceties of neotest
TEST_P(parameterized tests)- Build tool integration for recompilation - you have to do that manually (or with
Contributions are welcome! :)
Installation
Use your favorite package manager. Don't forget to install [neotest] itself, which also has a couple dependencies. The plugin also depends on plenary.nvim, chances are that so do your other plugins.
For debugging, you also need [nvim-dap], and a debug adapter ([codelldb] is recommended), you can install it manually or with [mason.nvim]. For setting it up, see [nvim-dap wiki][nvim-dap-wiki].
lazy.nvim
-- best to add to dependencies of neotest:
{
"nvim-neotest/neotest",
dependencies = {
"nvim-lua/plenary.nvim",
"alfaix/neotest-gtest"
-- your other adapters here
}
}
Usage
Simply add neotest-gtest to the adapters field of neotest's config:
require("neotest").setup({
adapters = {
require("neotest-gtest").setup({})
}
})
Before running tests, you need to assign them to executables. For that, navigate to the neotest summary window (neotest.summary.open()), mark the tests you want to run (m by default), and run :ConfigureGtest in that same window. It will prompt you to enter the path to the executable. You can set the executable path only for parent directory, no need to set it for each test separately. This configuration is persisted on disk.
Once that's done, use neotest the way you usually do: see their documentation. You don't need to call any neotest-gtest functions for ordinary usage.
Configuration
neotest-gtest comes with the following defaults:
local utils = require("neotest-gtest.utils")
local lib = require("neotest.lib")
require("neotest-gtest").setup({ -- fun(string) -> string: takes a file path as string and returns its project root -- directory -- neotest.lib.files.matchrootpattern() is a convenient factory for these functions: -- it returns a function that returns true if the directory contains any entries -- with matching names root = lib.files.matchrootpattern( "compile_commands.json", "compile_flags.txt", "WORKSPACE", ".clangd", "init.lua", "init.vim", "build", ".git" ), -- which debug adapter to use? dap.adapters.<this debug_adapter> must be defined. debug_adapter = "codelldb", -- fun(string) -> bool: takes a file path as string and returns true if it contains -- tests istestfile = function(file) -- by default, returns true if the file stem starts with test or ends with test -- the extension must be cpp/cppm/cc/cxx/c++ end, -- How many old test results to keep on disk (stored in stdpath('data')/neotest-gtest/runs) history_size = 3, -- To prevent large projects from freezing your computer, there's some throttling -- for -- parsing test files. Decrease if your parsing is slow and you have a -- monster PC. parsingthrottlems = 10, -- set configure to a normal mode key which will run :ConfigureGtest (suggested: -- "C", nil by default) mappings = { configure = nil }, summary_view = { -- How long should the header be in tests short summary? -- TestNamespace.TestName_ <- this is the header header_length = 80, -- Your shell's colors, if the default ones don't work. shell_palette = { passed = "\2732m", skipped = "\27[33m", failed = "\27[31m", stop = "\27[0m", bold = "\27[1m", }, }, -- What extra args should ALWAYS be sent to google test? -- if you want to send them for one given invocation only, -- send them to neotest.run({extra_args = ...}) -- see :h neotest.RunArgs for details extra_args = {}, -- see :h neotest.Config.discovery. Best to keep this as-is and set -- per-project settings in neotest instead. filterdir = function(name, relpath, root) -- see :h neotest.Config.discovery for defaults end, })
Contributing
All contributions are welcome. If you would like to contribute, but not sure how to get started, please open an issue, and I'll do my best to help you.
Should you feel confident enough to write a PR on your own, please make sure to include tests. The plugin is tested quite extensively, you can run make to run the tests. Integration testsuite requires a functioning C++11 compiler, and will download googletests as a submodule.
License
MIT, see [LICENSE
[nvim-treesitter]: https://github.com/nvim-treesitter/nvim-treesitter [neotest]: https://github.com/nvim-neotest/neotest [google-test]: https://github.com/google/googletest [nvim-dap]: https://github.com/mfussenegger/nvim-dap [codelldb]: https://github.com/vadimcn/codelldb [mason.nvim]: https://github.com/williamboman/mason.nvim [nvim-dap-wiki]: https://github.com/mfussenegger/nvim-dap/wiki/C-C---Rust-(via--codelldb)