2017-12-16
■[Vim] vader.vim をつかって E2E をやる
この記事は Vim Advent Calendar 2017 16日目の記事です。
「人は生まれたままの姿が一番美しい。ノーパンタイプ」に憧れるけど、風邪をひいちゃうので厚着の vimrc です。
TL;DR
- 日本語で vader.vim のことを書かれてるのを見たことないので書いた
- vader.vim 便利
Vim でテスト
以前作ったプラグインに不具合報告を頂くことがあった。手動で動作確認して直したり、新しい機能を作ったりしてて良くないなーと思っていた。
Vim でユニットテストといえば Vim 本体にとてもシンプルな assertion がある。
assert を書くだけでシンプルでわかりやすい。
ただし Vim にはテストランナーはないし*1、CI からも使うのめんどくさそうと思っていた。
日本のプラグイン作者界隈では themis.vim がよく使われてるようだが、自分で動かそうとしたけど思ったように動かなかった(完全に自分が悪い)のでめんどくさくなって、まぁ良いかと放置してた。
ある時「大幅に機能追加するから、その前にテスト書いたわ」というとてもありがたい PR をいただいた。
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 本体のテスト用にはあるが流用しがたい