Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running Neotest on a unittest folder fails when using unittest runner #69

Open
ColinKennedy opened this issue Mar 13, 2024 · 1 comment

Comments

@ColinKennedy
Copy link

ColinKennedy commented Mar 13, 2024

Demo

neotest_unittest_runner_directory_fail.mp4

Description

Reproduction Details

  • Load Neovim with the reproduction file
cd neotest_reproduction
PYTHONPATH=$PWD:$PYTHONPATH nvim -u reproduction_neotest_test.lua tests/test_something.py
  • Call :Neotest summary
  • In the Neotest right-hand window, press r on the tests folder
    • With the unittest runner enabled in reproduction_neotest_test.lua, it fails
    • With the pytest runner enabled in reproduction_neotest_test.lua, it succeeds

Reproduction Files

(You don't need this file, it's in the tar.gz. But pasted it here so people can see

reproduction.lua
-- DO NOT change the paths and don't remove the colorscheme
local root = vim.fn.fnamemodify("./.repro", ":p")

for _, name in ipairs({ "config", "data", "state", "cache" }) do
  vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
end

local lazypath = root .. "/plugins/lazy.nvim"

if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({ "git", "clone", "--filter=blob:none", "https://github.com/folke/lazy.nvim.git", lazypath, })
end

vim.opt.runtimepath:prepend(lazypath)

local plugins = {
    {
        "nvim-neotest/neotest",
        config = function()
            require("neotest").setup{
              adapters = {
                require("neotest-python")({
                    -- runner = "pytest",
                    runner = "unittest",
                })
              }
            }
        end,
        dependencies = {
            "antoinemadec/FixCursorHold.nvim",
            "nvim-lua/plenary.nvim",
            "nvim-treesitter/nvim-treesitter",

            "nvim-neotest/neotest-python",
        },
    },

    {
        "neovim/nvim-lspconfig",
        config = function()
            local lspconfig = require("lspconfig")
            local capabilities = vim.lsp.protocol.make_client_capabilities()

            lspconfig.jedi_language_server.setup { capabilities = capabilities }
        end,
    },
    {
        "nvim-treesitter/nvim-treesitter",
        build = ":TSUpdate",
        config = function()
            require('nvim-treesitter.configs').setup{
                ensure_installed = { 'python', 'query' },
            }
        end,
    },
}

require("lazy").setup(plugins, { root = root .. "/plugins" })

Expected

Running on the tests folder should still run as expected (or, if there was a subfolder, it should also run as expected). This is working for pytest but not for unittest.

The likely reason for the failure is because the test runner isn't sourcing tests/__init__.py when Neotest runs on a directory but tests/__init__.py is sourced when you run on a file. When I need to run unittests based on a directory, I typically do python -m unittest discover --start-directory tests/ or python -m unittest discover --start-directory tests/some_subfolder/ to make sure all __init__.py files are sourced correctly. Could neotest-python be adjusted to make sure tests run consistently regardless of the test's starting point?

@ColinKennedy
Copy link
Author

ColinKennedy commented Mar 13, 2024

I believe the issue is here: https://github.com/nvim-neotest/neotest-python/blob/27a2676aa02193d6ba4ad26238c09ededa49a9a7/neotest_python/unittest.py#L39C13-L39C51

The args are parsed as ["discover", "-s", path, *args]

Which in a unittest CLI situation would be

PYTHONPATH=$PWD:$PYTHONPATH python3 -m unittest discover --start-directory tests

Which isn't enough context for the unittest. According to unittest discover's help

  -t TOP, --top-level-directory TOP
                        Top level directory of project (defaults to start
                        directory)

When -s is given but -t is not, unittest discover assumes that the given directory is the top of the project so it doesn't search __init__.py from that point.

This fixes it

PYTHONPATH=$PWD:$PYTHONPATH python3 -m unittest discover --start-directory tests --top-level-directory .

When I adapted that solution to Neotest locally...

PYTHONPATH=$PWD:$PYTHONPATH python3 {root}/neotest-python/neotest.py --runner unittest --results-file /tmp/results --stream-file /tmp/stream -- tests --top-level-directory . blahblah_case_id

Now it works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant