42

我正在寻找一些用于测试 vim 脚本的工具。要么 vim 脚本

  • 进行单元/功能测试,或
  • 其他一些库(例如 Python 的unittest模块)的类,可以方便地
    • 使用参数运行 vim,使其对其环境进行一些测试,并且
    • 根据输出确定给定的测试是否通过。

我知道有几个 vim 脚本可以进行单元测试,但是它们的文档有点模糊,可能有用也可能没有用:

vim 单元

  • 声称“为 vim 脚本提供简单的单元测试框架和工具”
  • 第一个也是唯一一个版本 (v0.1) 于 2004 年发布
  • 文档没有提到它是否可靠地工作,只是说它是“从完成的票价 [原文如此]”。

单元测试.vim

  • 这个似乎也很实验性,可能不是特别可靠。
  • 可能已被放弃或搁置:最后一次提交是在 2009-11 年(> 6 个月前)
  • 没有创建标记修订(即没有发布)

因此,非常欢迎使用这两个现有模块之一的人们提供的信息,和/或指向其他更明确可用的选项的链接。

4

7 回答 7

19

vader.vim很简单,而且很棒。它没有外部依赖项(不需要 ruby​​/rake),它是一个纯 vimscript 插件。这是一个完全指定的测试:

Given (description of test):
  foo bar baz

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

Expect:
  foo bar ab
  cbaz

如果你打开了测试文件,你可以像这样运行它:

:Vader %

或者您可以指向文件路径:

:Vader ./test.vader
于 2013-11-01T02:59:24.837 回答
12

我已经成功地使用了Andrew Radev 的 VimrunnerRSpec来测试 Vim 插件并将它们设置在持续集成服务器上。

简而言之,Vimrunner 使用 Vim 的客户端-服务器功能来启动 Vim 服务器,然后发送远程命令,以便您可以检查(和验证)结果。它是一个 Ruby gem,因此您至少需要对 Ruby 有一定的了解,但是如果您投入时间,那么您将获得 RSpec 的全部功能来编写您的测试。

例如,一个名为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

如果您想了解更多详细信息,我已经在“使用 RSpec 和 Vimrunner 在 Travis CI 上测试 Vim 插件”中详细介绍了它。

于 2012-04-24T07:13:44.993 回答
9

我正在维护另一个(纯 Vimscript)UT 插件。

它被记录在案,带有几个示例,我的其他插件也使用它。

它旨在测试函数结果和缓冲区内容,并在快速修复窗口中显示失败。异常调用堆栈也被解码。AFAIK,它是迄今为止唯一(或至少是第一个)旨在填充快速修复窗口的插件。从那时起,我添加了帮助脚本以使用 rspec (+Vimrunner) 生成测试结果

从 v2.0(2020 年 5 月)开始,该插件还可以测试缓冲区内容——在它被映射/片段/...更改之后。直到那时我一直在使用其他插件。例如,我曾经使用 VimRunner+RSpec 在 travis 上测试我的 C++ 片段(来自 lh-cpp)。

关于语法,例如以下

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]

会产生:

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 {}

或者,如果我们想测试缓冲区内容

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

这导致

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

D在快速修复窗口中点击将在新选项卡中以差异模式打开生成的结果以及预期结果)

于 2010-06-14T06:20:58.590 回答
3

我以前用过vim-unit。至少这意味着您不必编写自己的AssertEqualsAssertTrue函数。它还有一个很好的功能,可以让您运行当前函数,如果它以“Test”开头,则只需将光标放在函数体中并键入:call VUAutoRun().

文档有点不确定和未完成,但是如果您有使用其他 XUnit 测试库的经验,那么您不会不熟悉。

提到的两个脚本都没有办法检查 vim 的特定功能——你不能改变缓冲区然后检查结果的期望——所以你必须以可测试的方式编写你的 vimscript。例如,将字符串传递给函数而不是将它们从getline()函数本身内部的缓冲区中提取出来,返回字符串而不是 using setline(),诸如此类。

于 2010-06-13T16:32:57.840 回答
1

vim-vspec。您的测试是用 vimscript 编写的,您可以使用 BDD 样式编写它们(describe, it, expect, ...)

runtime! plugin/sandwich/function.vim
describe 'Adding Quotes'
  it 'should insert "" in an empty buffer'
    put! = ''
    call SmartQuotes("'")

    Expect getline(1) == "''"
    Expect col('.') == 2
  end
end

GitHub 上有一个视频和一篇文章的链接,可以帮助您入门:

于 2017-06-15T13:44:19.827 回答
0

其他几个候选人:

VimBot - 与 VimRunner 类似,它是用 Ruby 编写的,允许您远程控制 vim 实例。构建为与单元测试框架 RSpec 一起使用。

VimDriver - 与 VimBot 相同,不同之处在于使用 Python 而不是 Ruby(作为 VimBot 的直接端口开始),因此如果您更熟悉 Python 的单元测试框架,则可以使用它。

于 2014-09-07T19:36:43.010 回答
0

对于功能测试,有一个名为vroom的工具。它有一些限制,并且可能需要几秒钟到几分钟的时间才能通过一个良好规模项目的全面测试,但它有一个很好的文字测试/文档格式,支持 vim 语法突出显示。

它用于测试codefmt插件和一些类似的项目。您可以在那里查看 vroom/ 目录以获取示例。

于 2015-02-11T02:09:00.893 回答