2

I'm working on a plug-in for Vim, and I'd like to test that it behaves correctly, under start-up, when users edit files e.t.c.

To do this, I'd like to start a terminal, and feed keys in to it. I'm thinking of doing it all from a python script. Is there a way to do this?

In pseudo-python it might look something like this:

#start a terminal. Here konsole
konsole = os.system('konsole --width=200 --height=150')

#start vim in that terminal
konsole.feed_keys("vim\n")
#run the vim function to be tested
konsole.feed_keys(":let my_list = MyVimFunction()\n")
#save the return value to the file system
konsole.feed_keys(":writefile(my_list, '/tmp/result')\n")

#load result into python
with open('/tmp/result', 'r') as myfile:
    data = myfile.read()

#validate the result
assertEqual('expect result', data)
XPlatformer
  • 1,148
  • 8
  • 18

2 Answers2

3

I think you should verify the core functionality of your plugin inside Vim, using unit tests. There's a wide variety of Vim plugins, but most provide some additional mappings or commands, to be invoked by the user, and they usually leave behind some side effects in the buffer, or output, or opened windows. That can be verified from inside Vim. There are a various approaches for that, mine is the runVimTests test framework; the plugin page has links to several alternatives.

With the core functionality thus covered, there's little left to test "interactively". (I mean stuff like forgotten debug output, too long execution times, display mess-ups.) Since you're usually a heavy user of Vim and your plugin yourself, that mostly covers it.


Of course, if your plugin embeds itself tightly into Vim (like an "IDE for XXX"; though this is usually frowned upon), you may consider some external test driver. Maybe others will contribute pointers to some general-purpose, terminal-driven test frameworks. I'm almost sure such exist.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • very useful answers from you and Luc Hermitte. I have set this answer to accepted, because this is closer to what I have decided to do. I put all my test code in a .vimrc file, which I copy to a tempdir. Then I start vim like this: `cd $tmpdir && HOME=. vim -X` And then I start the actual test on a vim8-timer, thus after the plugin has been loaded. – XPlatformer Nov 18 '16 at 14:29
  • Thanks, and happy testing; doing this systematically from the start has undeniable benefits! Your approach sounds good; if you do not want to rely on Vim version 8, you can also use `:autocmd VimEnter * call StartTests()` to trigger them. – Ingo Karkat Nov 18 '16 at 14:39
  • brilliant idea with the autocmd, but the script requires vim8 anyway :-) – XPlatformer Nov 18 '16 at 16:20
2

While I'm maintaining a plugin that permits to run unit tests on VimL functions and feed the quickfix window with the results, I use another couple of tools to check the state of the buffer after some actions, and even run the thing from travis -> vimrunner+rspec, and VimFlavour for installing the dependencies. (I vaguely remember a Python alternative inspired by vimrunner)

It mostly works well. Alas it uses the client-server feature and :redir (instead of the more recent execute() function). Even with the use of :silent, :redir catches noise which it returns to the client. Thus sometimes I fight tests that fail for very odd reasons. I also find myself inserting some pseudo-pauses to be sure that Vim has finished to interpret what I've feed it.

You'll find example of use in some of my plugins. See for instance lh-brackets or lh-cpp tests (.travis.yml file + .rspec/ directory + Rakefile + Gemfile + some helpers from vim-UT)

Luc Hermitte
  • 31,979
  • 7
  • 69
  • 83