{"id":13412605,"url":"https://github.com/nvim-neotest/neotest","last_synced_at":"2026-04-02T21:22:14.506Z","repository":{"id":37030150,"uuid":"443889454","full_name":"nvim-neotest/neotest","owner":"nvim-neotest","description":"An extensible framework for interacting with tests within NeoVim.","archived":false,"fork":false,"pushed_at":"2026-04-01T08:36:45.000Z","size":728,"stargazers_count":3055,"open_issues_count":95,"forks_count":174,"subscribers_count":12,"default_branch":"master","last_synced_at":"2026-04-01T09:29:55.455Z","etag":null,"topics":["lua","neovim"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nvim-neotest.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"rcarriga"}},"created_at":"2022-01-02T23:08:55.000Z","updated_at":"2026-04-01T08:36:06.000Z","dependencies_parsed_at":"2023-12-10T20:25:26.455Z","dependency_job_id":"c6377df4-aa93-4a6d-b951-5cfa3d325542","html_url":"https://github.com/nvim-neotest/neotest","commit_stats":{"total_commits":371,"total_committers":72,"mean_commits":5.152777777777778,"dds":0.3342318059299192,"last_synced_commit":"0dccb5ebcf00de245e2060fa17822a9464f5c41a"},"previous_names":["rcarriga/neotest"],"tags_count":176,"template":false,"template_full_name":null,"purl":"pkg:github/nvim-neotest/neotest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvim-neotest%2Fneotest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvim-neotest%2Fneotest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvim-neotest%2Fneotest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvim-neotest%2Fneotest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nvim-neotest","download_url":"https://codeload.github.com/nvim-neotest/neotest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvim-neotest%2Fneotest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31316599,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lua","neovim"],"created_at":"2024-07-30T20:01:26.698Z","updated_at":"2026-04-02T21:22:14.500Z","avatar_url":"https://github.com/nvim-neotest.png","language":"Lua","funding_links":["https://github.com/sponsors/rcarriga"],"categories":["Test","Lua","LUA"],"sub_categories":["Quickfix"],"readme":"# Neotest\n\nA framework for interacting with tests within NeoVim.\n\n![image](https://user-images.githubusercontent.com/24252670/166156510-440d9047-c76e-4967-8c17-944399222645.png)\n\n**This is early stage software.**\n\n- [Introduction](#introduction)\n- [Installation](#installation)\n  - [Supported Runners](#supported-runners)\n- [Configuration](#configuration)\n- [Usage](#usage)\n- [Consumers](#consumers)\n  - [Output Window](#output-window)\n  - [Summary Window](#summary-window)\n  - [Diagnostic Messages](#diagnostic-messages)\n  - [Status Signs](#status-signs)\n- [Strategies](#strategies)\n- [Writing Adapters](#writing-adapters)\n  - [Parsing tests in a directory](#parsing-tests)\n  - [Collecting results](#collecting-results)\n\n## Introduction\n\nSee `:h neotest` for details on neotest is designed and how to interact with it programmatically.\n\n## Installation\n\n[![LuaRocks](https://img.shields.io/luarocks/v/neotest/neotest?logo=lua\u0026color=purple)](https://luarocks.org/modules/neotest/neotest)\n\nNeotest uses [nvim-nio](https://github.com/nvim-neotest/nvim-nio) and [plenary.nvim](https://github.com/nvim-lua/plenary.nvim/).\n\nMost adapters will also require [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter).\n\nNeotest uses the `CursorHold` event. This uses the `updatetime`\nsetting which is by default very high, and lowering this can lead to excessive writes to disk.\nIt's recommended to use https://github.com/antoinemadec/FixCursorHold.nvim which\nallows detaching `updatetime` from the frequency of the `CursorHold` event.\nThe repo claims it is no longer needed but it is still recommended (See [this issue](https://github.com/antoinemadec/FixCursorHold.nvim/issues/13))\n\nInstall with your favourite package manager alongside nvim-dap\n\n[**dein**](https://github.com/Shougo/dein.vim):\n\n```vim\ncall dein#add(\"nvim-lua/plenary.nvim\")\ncall dein#add(\"antoinemadec/FixCursorHold.nvim\")\ncall dein#add(\"nvim-treesitter/nvim-treesitter\")\ncall dein#add(\"nvim-neotest/nvim-nio\")\ncall dein#add(\"nvim-neotest/neotest\")\n```\n\n[**vim-plug**](https://github.com/junegunn/vim-plug)\n\n```vim\nPlug 'nvim-lua/plenary.nvim'\nPlug 'antoinemadec/FixCursorHold.nvim'\nPlug 'nvim-treesitter/nvim-treesitter'\nPlug 'nvim-neotest/nvim-nio'\nPlug 'nvim-neotest/neotest'\n```\n\n[packer.nvim](https://github.com/wbthomason/packer.nvim)\n\n```lua\nuse {\n  \"nvim-neotest/neotest\",\n  requires = {\n    \"nvim-neotest/nvim-nio\",\n    \"nvim-lua/plenary.nvim\",\n    \"antoinemadec/FixCursorHold.nvim\",\n    \"nvim-treesitter/nvim-treesitter\"\n  }\n}\n```\n\n[lazy.nvim](https://github.com/folke/lazy.nvim)\n\n```lua\n{\n  \"nvim-neotest/neotest\",\n  dependencies = {\n    \"nvim-neotest/nvim-nio\",\n    \"nvim-lua/plenary.nvim\",\n    \"antoinemadec/FixCursorHold.nvim\",\n    \"nvim-treesitter/nvim-treesitter\"\n  }\n}\n```\n\nTo get started you will also need to install an adapter for your test runner.\nSee the adapter's documentation for their specific setup instructions.\n\n### Supported Runners\n\n| Test Runner           |                                                           Adapter                                                           |\n| :-------------------- | :-------------------------------------------------------------------------------------------------------------------------: |\n| pytest                |                              [neotest-python](https://github.com/nvim-neotest/neotest-python)                               |\n| python-unittest       |                              [neotest-python](https://github.com/nvim-neotest/neotest-python)                               |\n| plenary               |                             [neotest-plenary](https://github.com/nvim-neotest/neotest-plenary)                              |\n| go                    | [neotest-go](https://github.com/akinsho/neotest-go) \u003cbr\u003e [neotest-golang](https://github.com/fredrikaverpil/neotest-golang) |\n| jest                  |                                 [neotest-jest](https://github.com/haydenmeade/neotest-jest)                                 |\n| mocha                 |                                 [neotest-mocha](https://github.com/adrigzr/neotest-mocha)                                 |\n| vitest                |                               [neotest-vitest](https://github.com/marilari88/neotest-vitest)                                |\n| bun                   |                               [neotest-bun](https://github.com/arthur944/neotest-bun)                                       |\n| stenciljs             |                              [neotest-stenciljs](https://github.com/benelan/neotest-stenciljs)                              |\n| playwright            |                             [neotest-playwright](https://github.com/thenbe/neotest-playwright)                              |\n| rspec                 |                                 [neotest-rspec](https://github.com/olimorris/neotest-rspec)                                 |\n| minitest              |                               [neotest-minitest](https://github.com/zidhuss/neotest-minitest)                               |\n| ruby, minitest        |                               [neotest-ruby-minitest](https://github.com/volodya-lombrozo/neotest-ruby-minitest)            |\n| dart, flutter         |                                  [neotest-dart](https://github.com/sidlatau/neotest-dart)                                   |\n| testthat              |                            [neotest-testthat](https://github.com/shunsambongi/neotest-testthat)                             |\n| phpunit               |                               [neotest-phpunit](https://github.com/olimorris/neotest-phpunit)                               |\n| pest                  |                                   [neotest-pest](https://github.com/V13Axel/neotest-pest)                                   |\n| rust (treesitter)     |                                   [neotest-rust](https://github.com/rouge8/neotest-rust)                                    |\n| rust (LSP)            |                                   [rustaceanvim](https://github.com/mrcjkb/rustaceanvim)                                    |\n| elixir                |                                [neotest-elixir](https://github.com/jfpedroza/neotest-elixir)                                |\n| dotnet (treesitter)   |                               [neotest-dotnet](https://github.com/Issafalcon/neotest-dotnet)                                |\n| dotnet (vstest)       |                               [neotest-vstest](https://github.com/nsidorenco/neotest-vstest)                                |\n| scala                 |                                [neotest-scala](https://github.com/stevanmilic/neotest-scala)                                |\n| haskell               |                                [neotest-haskell](https://github.com/mrcjkb/neotest-haskell)                                 |\n| deno                  |                                 [neotest-deno](https://github.com/MarkEmmons/neotest-deno)                                  |\n| java                  |                                   [neotest-java](https://github.com/rcasia/neotest-java)                                    |\n| kotlin                |                             [neotest-kotlin](https://github.com/codymikol/neotest-kotlin.nvim)                              |\n| foundry               |                               [neotest-foundry](https://github.com/llllvvuu/neotest-foundry)                                |\n| zig                   |                                 [neotest-zig](https://github.com/lawrence-laz/neotest-zig)                                  |\n| c++ (google test)     |                                  [neotest-gtest](https://github.com/alfaix/neotest-gtest)                                   |\n| c++ (ctest)           |                                  [neotest-ctest](https://github.com/orjangj/neotest-ctest)                                  |\n| gradle                |                                [neotest-gradle](https://github.com/weilbith/neotest-gradle)                                 |\n| bazel                 |                                 [neotest-bazel](https://github.com/sluongng/neotest-bazel)                                  |\n| bash                  |                                   [neotest-bash](https://github.com/rcasia/neotest-bash)                                    |\n| hardhat               |                             [neotest-hardhat](https://github.com/TheSnakeWitcher/hardhat.nvim)                              |\n| swift (Swift Testing) |                           [neotest-swift-testing](https://github.com/mmllr/neotest-swift-testing)                           |\n| busted                |                           [neotest-busted](https://github.com/MisanthropicBit/neotest-busted)                           |\n| nix-unit              |                           [neotest-nix-unit](https://github.com/Jumziey/neotest-nix-unit.nvim)                              |\n\nFor any runner without an adapter you can use [neotest-vim-test](https://github.com/nvim-neotest/neotest-vim-test) which supports any runner that vim-test supports.\nThe vim-test adapter does not support some of the more advanced features such as error locations or per-test output.\nIf you're using the vim-test adapter then install [vim-test](https://github.com/vim-test/vim-test/) too.\n\n## Configuration\n\nProvide your adapters and other config to the setup function.\n\n```lua\nrequire(\"neotest\").setup({\n  adapters = {\n    require(\"neotest-python\")({\n      dap = { justMyCode = false },\n    }),\n    require(\"neotest-plenary\"),\n    require(\"neotest-vim-test\")({\n      ignore_file_types = { \"python\", \"vim\", \"lua\" },\n    }),\n  },\n})\n```\n\nSee `:h neotest.Config` for configuration options and `:h neotest.setup()` for the default values.\n\nIt is highly recommended to use [lazydev.nvim](https://github.com/folke/lazydev.nvim) to enable type checking for neotest to get\ntype checking, documentation and autocompletion for all API functions.\n\nThe default icons use [codicons](https://github.com/microsoft/vscode-codicons).\nIt's recommended to use this [fork](https://github.com/ChristianChiarulli/neovim-codicons) which fixes alignment issues\nfor the terminal. If your terminal doesn't support font fallback and you need to have icons included in your font, you can patch it via [Font Patcher](https://github.com/ryanoasis/nerd-fonts#option-8-patch-your-own-font).\nThere is a simple step by step guide [here](https://github.com/mortepau/codicons.nvim#how-to-patch-fonts).\n\n## Usage\n\nThe interface for using neotest is very simple.\n\nRun the nearest test\n\n```lua\nrequire(\"neotest\").run.run()\n```\n\nRun the current file\n\n```lua\nrequire(\"neotest\").run.run(vim.fn.expand(\"%\"))\n```\n\nDebug the nearest test (requires nvim-dap and adapter support)\n\n```lua\nrequire(\"neotest\").run.run({strategy = \"dap\"})\n```\n\nSee `:h neotest.run.run()` for parameters.\n\nStop the nearest test, see `:h neotest.run.stop()`\n\n```lua\nrequire(\"neotest\").run.stop()\n```\n\nAttach to the nearest test, see `:h neotest.run.attach()`\n\n```lua\nrequire(\"neotest\").run.attach()\n```\n\n## Consumers\n\nFor extra features neotest provides consumers which interact with the state of the tests and their results.\n\nSome consumers will be passive while others can be interacted with.\n\n### Watch Tests\n\n`:h neotest.watch`\n\nWatches files related to tests for changes and re-runs tests\n\nhttps://user-images.githubusercontent.com/24252670/229367494-6775d7f1-a8fb-461b-bbbd-d6124031293e.mp4\n\n### Output Window\n\n`:h neotest.output`\n\nDisplays output of tests\n![image](https://user-images.githubusercontent.com/24252670/166143146-e7821fe9-c11c-4e21-9cc0-73989b51e8ed.png)\n\nDisplays per-test output\n![image](https://user-images.githubusercontent.com/24252670/166143189-0f51b544-3aec-4cfc-93d7-74f3d209aef6.png)\n\n### Output Panel\n\n`:h neotest.output_panel`\n\nRecords all output of tests over time in a single window\n![image](https://user-images.githubusercontent.com/24252670/201535290-d726c781-a780-4318-b595-a10832b9f191.png)\n\n### Summary Window\n\n`:h neotest.summary`\n\nDisplays test suite structure from project root.\n![image](https://user-images.githubusercontent.com/24252670/166143333-df8b409f-d6f3-4d3d-a676-5f8a4a4cb8bb.png)\n\nProvides mappings for running, attaching, stopping and showing output.\n\n### Diagnostic Messages\n\n`:h neotest.diagnostic`\n\nUse vim.diagnostic to display error messages where they occur while running.\n\n![image](https://user-images.githubusercontent.com/24252670/166143466-0fdea24c-6f0a-4199-9026-66f89d7d1dbc.png)\n\n### Status Signs\n\n`:h neotest.status`\n\nDisplays the status of a test/namespace beside the beginning of the definition.\n\n![image](https://user-images.githubusercontent.com/24252670/166143402-b318ef91-c053-4973-b929-5ee97572f2c2.png)\n\nSee the help doc for a list of all consumers and their documentation.\n\n## Strategies\n\nStrategies are methods of running tests. They provide the functionality to attach to running processes and so attaching\nwill mean different things for different strategies.\n\n|    Name    | Description                                                                                                 |\n| :--------: | :---------------------------------------------------------------------------------------------------------- |\n| integrated | Default strategy that will run a process in the background and allow opening a floating terminal to attach. |\n|    dap     | Uses nvim-dap to debug tests (adapter must support providing an nvim-dap configuration)                     |\n\nCustom strategies can implemented by providing a function which takes a `neotest.RunSpec` and returns an table that fits the `neotest.Process`\ninterface. Plenary's async library can be used to run asynchronously.\n\n## Writing Adapters\n\nThis section is for people wishing to develop their own neotest adapters.\nThe documentation here and the underlying libraries are WIP and open to feedback/change.\nPlease raise issues with any problems understanding or using the this doc.\nThe best place to figure out how to create an adapter is by looking at the existing ones.\n\nAdapters must fulfill an interface to run (defined\n[here](https://github.com/nvim-neotest/neotest/blob/master/lua/neotest/adapters/interface.lua)).\n\nMuch of the functionality is built around using a custom tree object that defines the structure of the test suite.\nThere are helpers that adapters can use within their code (all defined under `neotest.lib`)\n\nAdapters must solve three problems:\n\n1. Parse tests\n2. Construct test commands\n3. Collect results\n\n### Parsing Tests\n\nThere are two stages to this, finding files which is often a simple file name check (it's OK if a test file has no\nactual tests in it) and parsing test files.\n\nFor languages supported by nvim-treesitter, the easiest way to parse tests is to use the neotest treesitter wrapper to parse a query to\nconstuct a tree structure.\n\nThe query can define capture groups for tests and namespaces. Each type must have `\u003ctype\u003e.name` and `\u003ctype\u003e.definition`\ncapture groups. They can be used multiple times in the query\n\nExample from neotest-plenary:\n\n```lua\nlocal lib = require(\"neotest.lib\")\n\nfunction PlenaryNeotestAdapter.discover_positions(path)\n  local query = [[\n  ;; describe blocks\n  ((function_call\n      name: (identifier) @func_name (#match? @func_name \"^describe$\")\n      arguments: (arguments (_) @namespace.name (function_definition))\n  )) @namespace.definition\n\n\n  ;; it blocks\n  ((function_call\n      name: (identifier) @func_name\n      arguments: (arguments (_) @test.name (function_definition))\n  ) (#match? @func_name \"^it$\")) @test.definition\n\n  ;; async it blocks (async.it)\n  ((function_call\n      name: (\n        dot_index_expression\n          field: (identifier) @func_name\n      )\n      arguments: (arguments (_) @test.name (function_definition))\n    ) (#match? @func_name \"^it$\")) @test.definition\n    ]]\n  return lib.treesitter.parse_positions(path, query, { nested_namespaces = true })\nend\n```\n\nFor languages unsupported by treesitter you can use regexes like neotest-vim-test or hook into the test runner.\n\n### Constructing Test Commands\n\nThis is the easiest part of writing an adapter. You need to handle the different types of positions that a user may run\n(directory, file, namespace and test).\n\nIf you are hooking into the runner, you may not be running the test runner command directly. neotest-python and\nneotest-plenary both are examples of this, with a script being used to run each runner to handle parsing results and\nstoring them for result collection later.\n\n### Collecting Results\n\nCollecting results will be the most involved process in the adapter, with complexity depending on the test runner and\ndesired features.\n\nFor the most basic implementation an adapter can choose to only run tests individually and use the exit code as an\nindicator of the result (this is how neotest-vim-test works) but this impacts peformance and also loses out on more\nadvanced features.\n\nIf tests can be run together then the adapter must provide results for at least each individual test. Results for\nnamespaces, files and directories will be inferred from their child tests.\n\nFor collecting test specific error messages, error locations etc you'll need to parse output or hook into the runner.\nSee neotest-python and neotest-plenary for examples on how this can be done.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvim-neotest%2Fneotest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnvim-neotest%2Fneotest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvim-neotest%2Fneotest/lists"}