I have managed to automate this feature using vimscript-python. Add this function to your ~/.vimrc
:
function! RunCurrentPythonTest()
python3 << EOF
import re
import vim # https://vimhelp.org/if_pyth.txt.html
cursor = vim.current.window.cursor
test_filename = vim.eval("expand('%p')")
test_name = None
class_name = None
for line_no in range(cursor[0]-1, -1, -1):
line = vim.current.buffer[line_no]
if not test_name and line.lstrip().startswith('def test'):
test_name = re.findall('def (\w+)\(', line)[0]
if not class_name and line.startswith('class'):
class_name = re.findall('class (\w+)\(', line)[0]
break
cmd = f'!pytest {test_filename}'
if class_name:
cmd += f'::{class_name}'
if test_name:
cmd += f'::{test_name}'
vim.command(cmd)
EOF
endfunction
And map this function to ;t
:
map ;t :call RunCurrentPythonTest()<CR>
Hover on a Python test, press ;t
and great success - only that one test is executed:
================================================================== FAILURES ===================================================================
____________________________________________________________ MyTestCase.test_false ____________________________________________________________
self = <my_tests.MyTestCase testMethod=test_false>
def test_false(self):
> self.assertFalse(True)
E AssertionError: True is not false
bin/my_tests.py:9: AssertionError
============================================================== 1 failed in 0.04s ==============================================================
This implementation has additional feature: If you hover on a TestCase definition line - whole test case will be executed. And if you navigate to the begging of the file - all tests of the file will be executed.
search()
calls to get the nearest def/class lines, and then you’d need to parse out the names... I can try to mock something up this evening