I have the feeling that the answer is you can't, but I'd like to be sure about it.

My plugin has some s:function-name functions, and one plugin-name#function-name function that uses the former ones.

Is there a way to write unit tests for those s: functions? For instance, could I do it via Vader?

2 Answers 2


When I have internal functions that I want to test, I don't declare them as s: functions but with a different naming policy like mypluginscope#_whatever(). This way testing them is not an issue and I keep s:functions really internal.

Otherwise there is a way to find script-local functions from the name of the plugin. We have to find the ScriptNumbeR of the file (by analysing execute(':scriptname'), and then forge the function name with <SNR>{thenumber}_{thefunctionname}.

I've described the approach to obtain and reference such functions in two Q/A on SO:

I did write that the SNR could be obtained for foobar.vim with:

let snr = matchstr(matchstr(split(execute('scriptnames'), "\n"), 'foobar.vim'), '^ *\d\+')

and then the function s:foo from foobar.vim could be used with

let Foo = function('<SNR>'.snr.'_foo')
echo Foo(42)

Note: I cannot tell whether this solution could be used with vader, but at least it should work perfectly with my unit testing plugin for Vim Scripts -- given the way it works: sourcing vim files and all.

  • The get-the-SNR approach works pretty well. I needed to match autoload/foobar.vim, which you couldn't know. Besides, '^ *\d\+' should be used instead of '^\d\+' because the numbers in the first column of :scriptnames are right aligned, so you get some leading space for those numbers with less digits than the maximum number.
    – Enlico
    Feb 3, 2022 at 7:07
  • I'm not surprised the pattern is not 100% correct ^^'. Actually since then I've industrialized the search in a function of my library plugin. Feb 3, 2022 at 10:11

I have a plugin that I use to do unit tests on my vim-surround-funk plugin (it can only check if the contents of one buffer after applying some normal mode commands is identical to the contents of an 'expected output buffer'). It's not documented, and I never really planned on releasing it for others to use, but it's only 250 lines of code so maybe you can have a look at that and roll your own solution (or even just try to use my one). Another option is to change all your function names from s:myfunction() to regular MyFunction() and source the script directly.

  • Well, the point is that my plugin is not for editing text, but for editing windows layout, so there's no expected vs actual text.
    – Enlico
    Feb 2, 2022 at 21:11
  • @Enlico ah ok then maybe you can look for a real unit-testing vimscript framework like this one (although I don't know if it can handle window layouts). You might have to write your own set of functions to do it (if you deem it worth your time)
    – mattb
    Feb 2, 2022 at 21:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.