Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tools for testing vim plugins

I'm looking for some tools for testing vim scripts. Either vim scripts that

  • do unit/functional testing, or
  • classes for some other library (eg Python's unittest module) that make it convenient to
    • run vim with parameters that cause it to do some tests on its environment, and
    • determine from the output whether or not a given test passed.

I'm aware of a couple of vim scripts that do unit testing, but they're sort of vaguely documented and may or may not actually be useful:

vim-unit:

  • purports "To provide vim scripts with a simple unit testing framework and tools"
  • first and only version (v0.1) was released in 2004
  • documentation doesn't mention whether or not it works reliably, other than to state that it is "fare [sic] from finished".

unit-test.vim:

  • This one also seems pretty experimental, and may not be particularly reliable.
  • May have been abandoned or back-shelved: last commit was in 2009-11 (> 6 months ago)
  • No tagged revisions have been created (ie no releases)

So information from people who are using one of those two existent modules, and/or links to other, more clearly usable, options, are very welcome.

like image 543
intuited Avatar asked Jun 12 '10 19:06

intuited


People also ask

What is plugin testing?

As part of your plugin, you can write automated tests to check that everything works as expected. These tests run inside the same JavaScript environment as your plugin, so you can call any functions provided by the Platform or your plugin.

What is vim plugin manager?

vim-plug is a lightweight and powerful plugin manager that is easy to set up and use. All configurations and plugins are listed in a single file. It only has a few commands so you won't need to memorize anything to use the tool. vim-plug also supports parallel installation and updating of multiple plugins at a time.


3 Answers

vader.vim is easy, and amazing. It has no external dependencies (doesn't require ruby/rake), it's a pure vimscript plugin. Here's a fully specified test:

Given (description of test):
  foo bar baz

Do (move around, insert some text):
  2Wiab\<Enter>c

Expect:
  foo bar ab
  cbaz

If you have the test file open, you can run it like this:

:Vader %

Or you can point to the file path:

:Vader ./test.vader
like image 181
Justin M. Keyes Avatar answered Oct 23 '22 15:10

Justin M. Keyes


I've had success using Andrew Radev's Vimrunner in conjunction with RSpec to both test Vim plugins and set them up on a continuous integration server.

In brief, Vimrunner uses Vim's client-server functionality to fire up a Vim server and then send remote commands so that you can inspect (and verify) the outcome. It's a Ruby gem so you'll need at least some familiarity with Ruby but if you put the time in then you get the full power of RSpec in order to write your tests.

For example, a file called spec/runspec.vim_spec.rb:

require "vimrunner"
require "fileutils"

describe "runspec.vim" do
  before(:suite) do
    VIM = Vimrunner.start_gui_vim
    VIM.add_plugin(File.expand_path('../..', __FILE__), 'plugin/runspec.vim')
  end

  after(:all) do
    VIM.kill
  end

  it "returns the current path if it ends in _test.rb" do
    VIM.echo('runspec#SpecPath("foo_test.rb")').should == "foo_test.rb"
    VIM.echo('runspec#SpecPath("bar/foo_test.rb")').should == "bar/foo_test.rb"
  end

  context "with a spec directory" do
    before do
      FileUtils.mkdir("spec")
    end

    after do
      FileUtils.remove_entry_secure("spec")
    end

    it "finds a spec with the same name" do
      FileUtils.touch("spec/foo_spec.rb")
      VIM.echo('runspec#SpecPath("foo.rb")').should == "spec/foo_spec.rb"
    end
  end
end

I've written about it at length in "Testing Vim Plugins on Travis CI with RSpec and Vimrunner" if you want more detail.

like image 34
Paul Mucur Avatar answered Oct 23 '22 14:10

Paul Mucur


There is another (pure Vimscript) UT plugin that I'm maintaining.

It is documented, it comes with several examples, and it is also used by my other plugins.

It aims at testing function results and buffer contents, and displaying the failures in the quickfix window. Exception callstacks are also decoded. AFAIK, it's the only plugin so far (or at least the first) that's meant to fill the quickfix window. Since then, I've added helper scripts to produce test results with rspec (+Vimrunner)

Since v2.0 (May 2020), the plugin can also test buffer content -- after it has been altered with mappings/snippets/.... Up until then I've been using other plugins. For instance, I used to test my C++ snippets (from lh-cpp) on travis with VimRunner+RSpec.

Regarding the syntax, for instance the following

Assert 1 > 2
Assert 1 > 0
Assert s:foo > s:Bar(g:var + 28) / strlen("foobar")

debug AssertTxt (s:foo > s:Bar(g:var+28)
      \, s:foo." isn't bigger than s:Bar(".g:var."+28)")
AssertEquals!('a', 'a')
AssertDiffers('a', 'a')
let dict = {}
AssertIs(dict, dict)
AssertIsNot(dict, dict)
AssertMatch('abc', 'a')
AssertRelation(1, '<', 2)
AssertThrows 0 + [0]

would produce:

tests/lh/README.vim|| SUITE <[lh#UT] Demonstrate assertions in README>
tests/lh/README.vim|27 error| assertion failed: 1 > 2
tests/lh/README.vim|31 error| assertion failed: s:foo > s:Bar(g:var + 28) / strlen("foobar")
tests/lh/README.vim|33 error| assertion failed: -1 isn't bigger than s:Bar(5+28)
tests/lh/README.vim|37 error| assertion failed: 'a' is not different from 'a'
tests/lh/README.vim|40 error| assertion failed: {} is not identical to {}

Or, if we want to test buffer contents

silent! call lh#window#create_window_with('new') " work around possible E36
try
    " :SetBufferContent a/file/name.txt 
    " or
    SetBufferContent << trim EOF
    1
    3
    2
    EOF

    %sort

    " AssertBufferMatch a/file/NAME.txt
    " or
    AssertBufferMatch << trim EOF
    1
    4
    3
    EOF
finally
    silent bw!
endtry

which results into

tests/lh/README.vim|78 error| assertion failed: Observed buffer does not match Expected reference:
|| ---
|| +++
|| @@ -1,3 +1,3 @@
||  1
|| -4
|| +2
||  3

(hitting D in the quickfix window will open the produced result alongside the expected result in diff mode in a new tab)

like image 9
Luc Hermitte Avatar answered Oct 23 '22 16:10

Luc Hermitte