Sitemap
Better Programming

Advice for programmers.

LunarVim Debugging & Testing Python Code

5 min readMay 3, 2023

--

Press enter or click to view image in full size

This article is a follow-up article to LunarVim as a Python IDE. In this article, we will explore how to set up debugging and testing.

We will be installing and configuring various plugins to provide a streamlined debugging and testing experience.

You can find the complete final config at this GitHub repo.

Install Plugins

We will be installing three plugins to get started:

You can add the plugins to your LunarVim config file like this:

lvim.plugins = {
"mfussenegger/nvim-dap-python",
"nvim-neotest/neotest",
"nvim-neotest/neotest-python",
}

Setup Debug Adapter

LunarVim already includes two plugins for enabling dap and a rich visual experience using, nvim-dap, and nvim-dap-ui. So you just need to enable dap and setup your debug adapter.

In this case, we’ll be setting up debugpy as our adapter.

lvim.builtin.dap.active = true
local mason_path = vim.fn.glob(vim.fn.stdpath "data" .. "/mason/")
pcall(function()
require("dap-python").setup(mason_path .. "packages/debugpy/venv/bin/python")
end)

We will also need to install debugpy, luckily Mason makes this a very easy task. Just enter, press 3 to go to the debug adapter section, and press i on debugpy.

Setup Testing Support with Neotest

We’ll be using Neotest for running our tests. With Neotest we’ll be able to do things like run individual tests, get visual feedback about the status of our tests, and more.

For this example, we’ll be using pytest as our test runner.

require("neotest").setup({
adapters = {
require("neotest-python")({
dap = {
justMyCode = false,
console = "integratedTerminal",
},
args = { "--log-level", "DEBUG", "--quiet" },
runner = "pytest",
})
}
})

For more configuration options check out this link.

Set up Keybindings

This section might look a little complicated but all we’re doing is adding some keybindings to our leader key menu that pops up when you press space. For instance, pressing space d m will test the nearest method.

lvim.builtin.which_key.mappings["dm"] = { "<cmd>lua require('neotest').run.run()<cr>",
"Test Method" }
lvim.builtin.which_key.mappings["dM"] = { "<cmd>lua require('neotest').run.run({strategy = 'dap'})<cr>",
"Test Method DAP" }
lvim.builtin.which_key.mappings["df"] = {
"<cmd>lua require('neotest').run.run({vim.fn.expand('%')})<cr>", "Test Class" }
lvim.builtin.which_key.mappings["dF"] = {
"<cmd>lua require('neotest').run.run({vim.fn.expand('%'), strategy = 'dap'})<cr>", "Test Class DAP" }
lvim.builtin.which_key.mappings["dS"] = { "<cmd>lua require('neotest').summary.toggle()<cr>", "Test Summary" }

Keybindings explanation:

  • space d m: runs the nearest test
  • space d M: runs the nearest test in debug mode
  • space d f: runs all tests in file
  • space d F: runs all tests in file in debug mode
  • space d S: displays summary for tests

Setting up our tests

Now we’re ready to start debugging and testing some Python code.

Get chris@machine’s stories in your inbox

Join Medium for free to get updates from this writer.

To get started clone the following repo containing some example Python code with pytest unit tests:

git clone https://github.com/ChristianChiarulli/pytest_example.git
cd pytest_example

Now we’ll need to install pytest. Use whatever virtual environment manager you want. I’ll be using conda.

conda create -n pytest python -y
conda activate pytest
conda install - file requirements.txt

Before we get started debugging with LunarVim, let’s make sure all of the tests pass by running:

pytest tests/

You should see some indication that all of the tests have run and were successful.

=========================================== test session starts ===========================================
platform darwin - Python 3.11.3, pytest-7.3.1, pluggy-1.0.0
rootdir: /Users/chris/Repos/pytest_example
collected 5 items
tests/test_calculator.py ….. [100%]
============================================ 5 passed in 0.01s ============================================

Testing with LunarVim

Now we’re ready to start testing with LunarVim. To get started open the test_calculator.py file.

lvim tests/test_calculator.py

Hover over a unit test and press space d m. This should test the nearest method.

Press enter or click to view image in full size

To run all of the tests at once you can press space d f. You should notice little green check marks next to each test indicating they all passed.

Press enter or click to view image in full size

To see a summary of all of the unit tests and the status for each test you can press space d S.

Press enter or click to view image in full size

Debugging Tests

Now try adding a breakpoint to one of the tests with space d t. A little red bug should show up next to the line where you added the breakpoint.

Press enter or click to view image in full size

You can now try running the test in debug mode with space d M. You should notice that the test has paused at your breakpoint and will continue after you press space d c to continue. You should also notice that some UI elements were added as well showing scopes, breakpoints, stacks, watches, debug controls, and terminal output.

Press enter or click to view image in full size

You can view all of the commands for debugging by pressing space d and waiting for 1 second for the menu to show up.

Press enter or click to view image in full size

Conclusion

Throughout this article, we have explored how to set up debugging and testing for Python using LunarVim.

We have installed and configured various plugins, set up the debug adapter, and configured Neotest for running tests. We have also demonstrated how to set up keybindings and debug tests using LunarVim.

With these tools at your disposal, you can now focus on writing high-quality, bug-free code and ensure that your Python projects run smoothly and efficiently.

Note: if you want to take a deeper dive into what the debug adapter protocol is checkout this article.

--