echasnovski / mini.nvim

Library of 40+ independent Lua modules improving overall Neovim (version 0.8 and higher) experience with minimal effort
MIT License
4.47k stars 175 forks source link

[mini.test] add ability to isolate only one test in a test file to be run in the CLI #911

Closed MagicDuck closed 1 month ago

MagicDuck commented 1 month ago

Contributing guidelines

Module(s)

mini.test

Description

Sometimes, when debugging a particular test, it is good to be able to run only that test. In other test frameworks like jest, there is it.only(), so you would change from it() -> it.only() and only that specific test would run from the file. with the mini.test specific syntax, there would have to be some different adaption I guess. Not sure, maybe something like:

local T = MiniTest.new_set({})
T['test1'] = function() ... end
T['test2'] = MiniTest.only(T, function() ... end)
T['test3'] = function() ... end

where MiniTest.only() would add some info to T so that when T is run it skips all test functions that do not match the given function.

Note that running the test case direct from nvim in a floating window is not as appealing to me, as I like to have the output in another terminal tab so I can refer to current output as well as previous outputs. I prefer to run it through my Makefile:

# Run test from file at `$FILE` environment variable, ex: make test-file FILE=...
test-file:
    nvim --headless --noplugin -u ./scripts/minimal_init.lua -c "lua MiniTest.run_file('$(FILE)')"
echasnovski commented 1 month ago

Thanks for the suggestion!

Note that running the test case direct from nvim in a floating window is not as appealing to me, as I like to have the output in another terminal tab so I can refer to current output as well as previous outputs.

Indeed, the currently suggested approach is to use run_at_location(). I find that when mapped (for example, <Leader>tl for me) it provides a very streamlined workflow. If you want to inspect the output later, you can copy and paste in a scratch buffer.

I'll think about it, but at the moment I don't think adding this functionality will be a good idea.

echasnovski commented 1 month ago

After refreshing my memory about how 'mini.test' works and what it can do, this is already possible with run_at_location(). It accepts location as file and line number.

With slight modification of [test_file Make target]() the following is possible:

test_location:
    for nvim_exec in $(NVIM_EXEC); do \
        printf "\n======\n\n" ; \
        $$nvim_exec --version | head -n 1 && echo '' ; \
        $$nvim_exec --headless --noplugin -u ./scripts/minimal_init.lua \
            -c "lua require('mini.test').setup()" \
            -c "lua MiniTest.run_at_location({ file = '$(FILE)', line = $(LINE) }, { execute = { reporter = MiniTest.gen_reporter.stdout({ group_depth = $(GROUP_DEPTH) }) } })" ; \
    done

Now CLI calls like NVIM_EXEC="nvim_07 nvim_09" FILE=tests/test_test.lua LINE=332 make test_location will test case in 'tests/test_test.lua' file at line 332 with nvim_07 and nvim_09 Neovim executables.

Of course, modify this Makefile entry to fit your taste. I think setting LINE environment variable is a reasonable alternative to the suggested only decorator.

Closing as already possible.

MagicDuck commented 1 month ago

ah, that's a really neat way of doing it, and might actually be nicer than only since I don't have to edit the file, and cannot forget to remove it later, haha!

Awesome, I'll add that to my Makefile!

MagicDuck commented 1 month ago

Just for posterity, having multiple test targets like test_file, test_locatoin was a bit annoying so what I ended up doing was creating a new file scripts/test_cli.lua:

local MiniTest = require('mini.test')
local file = vim.env.file
local line = vim.env.line
local group_depth = vim.env.group_depth

if file then
  if line then
    MiniTest.run_at_location({
      file = file,
      line = tonumber(line),
    }, {
      execute = {
        reporter = MiniTest.gen_reporter.stdout({ group_depth = group_depth }),
      },
    })
  else
    MiniTest.run_file(file)
  end
else
  MiniTest.run()
end

and having only one test target in my Makefile:

# Run tests
# use with update_screenshot=true to update the screenshots
# use with file=... to test a particular file
# use with line=... to target a test at that line in the file 
test:
    nvim --headless --noplugin -u ./scripts/minimal_init.lua -l ./scripts/test_cli.lua

So calling it would work like:

make test file=tests/test_history.lua line=83
echasnovski commented 1 month ago

Just for posterity, having multiple test targets like test_file, test_locatoin was a bit annoying so what I ended up doing was creating a new file scripts/test_cli.lua:

Yeah, that's a good idea. I thought about doing this myself. Just need to figure out a good way to also handling multiple Neovim version testing. But this is a good starting point. Thank you!