vader.vim をつかって E2E をやる

この記事は Vim Advent Calendar 2017 16日目の記事です。
「人は生まれたままの姿が一番美しい。ノーパンタイプ」に憧れるけど、風邪をひいちゃうので厚着の vimrc です。


TL;DR

  • 日本語で vader.vim のことを書かれてるのを見たことないので書いた
  • vader.vim 便利

Vim でテスト

以前作ったプラグインに不具合報告を頂くことがあった。手動で動作確認して直したり、新しい機能を作ったりしてて良くないなーと思っていた。

Vimユニットテストといえば Vim 本体にとてもシンプルな assertion がある。
GitHub - mattn/vim-left-pad
assert を書くだけでシンプルでわかりやすい。
ただし Vim にはテストランナーはないし*1、CI からも使うのめんどくさそうと思っていた。


日本のプラグイン作者界隈では themis.vim がよく使われてるようだが、自分で動かそうとしたけど思ったように動かなかった(完全に自分が悪い)のでめんどくさくなって、まぁ良いかと放置してた。


ある時「大幅に機能追加するから、その前にテスト書いたわ」というとてもありがたい PR をいただいた。
Add tests and fix some issues by letientai299 · Pull Request #14 · heavenshell/vim-pydocstring · GitHub


PR のテストは vader.vim が使われていた。
vader.vim の存在は知っていたけど、README を読んで初見はめんどくさそうというイメージを持っていた。
せっかく頂いた PR を見てみるととてもシンプルな書き方で驚いた。

Given python (def foo with 1 param):
    def foo(arg):
        pass

Execute:
    Pydocstring

Expect python:
    def foo(arg):
        """foo

        :param arg:
        """
        pass

この場合 1 つめのブロックの状態が Vim 上にあることになる。
つまり

def foo(arg):
    pass

というファイルがあり、2 つめのブロックは

:Pydocstring

というコマンドを実行し、その結果が 3 つめのブロックをあらわし

def foo(arg):
    """foo

    :param arg:
    """
    pass

となるのを確認する。

テストの実行方法

$ /Applications/MacVim.app/Contents/MacOS/Vim -Nu minimal_vimrc -R '+Vader! *.vader'

こんな感じで Vim から vader を起動し実行する。
Mac だとシステムの Vim は古いので MacVim を指定する。
普段使いの vimrc を使うよりもシンプルな vimrc を指定した方が良いので、テスト用の vimrc を用意する。

set nocompatible
filetype off
" Clear all rtp
set rtp=$VIMRUNTIME

" Add vader.vim to rtp
set rtp+=./vader.vim

" Add pydocstring folder into rtp
set rtp+=../
filetype plugin indent on

CI で動かすように テストファイルが置いてあるディレクトリに vader.vim を置く。
これで Run time path に vader.vim が追加されて、vader.vim が動くようになる。

vader.vim の印象

関数単位のユニットテストというよりも E2E のテストライブラリ。
基本的に Execute ブロックに Vim で実行するコマンド(大抵はプラグインのコマンド)を記述し、コマンドの実行結果を Expect ブロックに書くため、xUnit や RSpec 系のテストの書き方と違って Vim に特化した DSL という感じがする。
コマンドを実行してその結果がどうなっているかというのを確認するというのに特化していると思う。

vader.vim での assertion

とはいえ vader.vim では Expect ブロックに結果を書いてテストするが assertion もかける。


vim-prettier という Prettier を Vim から実行して整形するプラグインを書いた時はそれも使った。
vim-prettier/prettier.vader at master · heavenshell/vim-prettier · GitHub

まとめ的なの

Vim script はスクリプトスコープな関数をテストから簡単に呼べなくて、テストを書くのが面倒だと思っていたが、E2E から始めりゃいいんだと気づかせてくれた。
vader.vim の PR を頂いた後に自分でテストランナーとか書いてみたけど、vader.vim で良いかと思うようになった。


個人的なポリシーとして自分の Vim プラグインは極力外部のものに依存したくないが、テスト系は例外とした。
(プラグイン本体を使うのにインストールされてなくても影響ないため)


とにかく簡単にテストを始められるのでオススメ。

*1:Vim 本体のテスト用にはあるが流用しがたい