Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

NeoBundle + Vesting 使ってVim plugin テストを自動化

$
0
0

はじめに

最近, Vim pluginを開発するようになって, テストをCIでぶん回したくなったので, 試行錯誤の結果メモ.

やりたいこと

僕はあんまりテストに深い思い入れがある訳ではないのだけど, 下記を実現したい気持ちがあった.

  1. コーディング中はVimから単体テストを実行したい.
  2. CIでもテストを回したいため, CLIからの実行も欲しい. READMEに"build passing"のバッジ貼りたい.
  3. テストを実行するための依存プラグイン管理の仕組みが欲しい.

Vim plguinのCIについて適当にググってみたところ, vim-flavorでテストをCLIから実行する, という方法が見つかったのだが, これは上記の1. と3. と背反するため, 今回は採用見送り.
また, vim-flavorは依存プラグインのバージョン指定がsemverに従ってないと上手く動作しない様子だったため, これも採用見送りの理由の一つ.

結局, 上記を全部充足するようなVimプラグインは特に見つからなかったので, NeoBundle + vesting + シェルスクリプトの構成を採用することにした.
NeoBundleは普段から使っているplugin manager, という理由.
vestingについては, 特に深い思いがある訳ではないが, NeoBundleと作者が一緒であり, 上記の1.に対応していたため.

やってみた

基本的な考え方

先述の通り, Vimを立ち上げてからの実行はvestingで出来るので, 作り込む必要があるのはCLI部分のみ.
今回は以下のアプローチでやってみた.

  1. レポジトリにneobundle.vimをclone.
  2. テスト用の.vimrcを用意し, テストに必要なVimの設定情報は事前に記述しておく.
    • プラグイン本体, NeoBundleのruntimepath設定はこのファイルに記述
    • テスト実行時に必要となる依存pluginはこのファイル中に:NeoBundleコマンドで列挙し, :NeoBundleInstallで取得する
  3. vestingを実行するためのマクロを用意する.
    • vestingはUniteで結果を出力するため, この結果をログに吐き出すようにしておく.
  4. Vimをsilent-modeで起動する. vim -u vest/.vimrc -s vest/_runner.
  5. vestの結果ログに[Fail], [Error]が存在するかどうか, grepする. 該当無しであればテスト成功とみなす.

コード解説

さて, 実際にQuramy/vesting-ciにサンプルのレポジトリ作って, TravisCIで動かしてみた.

レポジトリのディレクトリ構成は下記のようにしている.

ディレクトリ構成
- vesting-ci           # レポジトリのルート. 
 - autoload/
  |  calc.vim          # テスト対象コード
 + bundle/             # NeoBundleでinstallするpluginディレクトリ
 + neobundle.vim/      # NeoBundle本体
 - vest/               # vestingのテストコード用ディレクトリ
  |  .vimrc            # 2.の設定ファイル
  |  _runner           # 3.のvesting実行マクロ
  |  calc_add.vim      # vestingのテストコードその1
  |  calc_sub.vim      # vestingのテストコードその2
 + vim/
   runtest.sh          # CLI用シェルスクリプト
   .travis.yml         # TraviceCI設定ファイル

vestingはカレントディレクトリ配下のvest/*.vimをテストコードとみなして実行するため, テスト関係のファイルは極力ここに突っ込むようにした.

テスト対象のコードは下記. と言っても只の足し算と引き算.

autoload/calc.vim
function! calc#add(a,b)returna:a+a:bendfunctionfunction! calc#sub(a,b)returna:a-a:bendfunction

対応するvestingのテストコードは下記.

vest/calc_add.vim
scriptencoding utf-8

Context Vesting.run()
  It calc#add returns the summation of two values
    Should calc#add(1,2)==3
  End
End
Fin

vest/calc_sub.vimも似たような感じ. ちなみに, vestingは:Unite vesting:.をVimから実行すると, テストの一覧がUnite上に表示されるので, 実行したいテストファイルを選択してEnterを叩くとテストが実行される.

ここからがこのエントリの主眼. まずは上記2. の.vimrcから.

vest/.vimrc
if has('vim_starting')setnocompatiblelets:basedir = expand('<sfile>:p:h').'/../'  " プラグイン自体をruntimepathに登録.
  execute('set runtimepath+='.s:basedir)  " NeoBundleをruntimepathに登録.
  execute('set runtimepath+='.s:basedir.'neobundle.vim')  " NeoBundleで依存pluginを記載.  " Uniteとvestingは必須.call neobundle#begin(expand(s:basedir.'bundle'))
  NeoBundle 'Shougo/unite.vim'
  NeoBundle 'Shougo/vesting'call neobundle#end()  " 必要なpluginの一括installsilent NeoBundleInstall
endif

Uniteとvestingは最低限必要となるpluginである. もし, 他に必要なpluginがあれば, NeoBundleを追記していけばよい.
(僕が実際に開発しているPluginでは, vimprocを使ってるいるが, このファイルに追記している)

続いて3.のvesting実行マクロ.

vest/_runner
:Unite vesting:.
*
:call unite#action#do('start'):w vest/test_result.log
:quitallvim:ft=vim

vestingを実行した後, *で全テストファイルを選択. uniteのstart actionを実行すると, 全テストが実行されて結果がUniteのバッファに表示されるので, これをファイルに保存するようにしている.
あんまりスマートじゃない気もするが, 取り合えず動いてるのでこれでよし.
なお, このファイルの拡張子に.vimを付けてないのは, vestingがテストコードだと誤解しないようにするため.

最後にCLI用のシェルスクリプトとTravisCIの設定ファイル.
実際はディレクトリの存在チェックとか, Vim自体のビルド処理(TravisCIのVimが7.3で古いので)も書いているため, もう少し長くなるのだけど, 先述した方法の骨子を抜きだすとこんな感じだ.

runtest.sh
#/bin/shVIMRC_FILE="vest/.vimrc"DRIVER_FILE="vest/_runner"RESULT_FILE="vest/test_result.log"# 1. NeoBundleのクローン
git clone https://github.com/Shougo/neobundle.vim

# 4. Vestingの実行
vim -u ${VIMRC_FILE} -s ${DRIVER_FILE}
cat ${RESULT_FILE}# 5. テスト結果の判定
grep -E "\[Fail\]"${RESULT_FILE}> /dev/null
if[$? -eq 0];thenexit 1
fi
grep -E "\[Error\]"${RESULT_FILE}> /dev/null
if[$? -eq 0];thenexit 1
fi
.travis.yml
script:-sh runtest.sh

所感

最初はVim plguinのCI化は結構敷居が高そうに思っていたが, やってみると意外と簡単.

テスティングフレームワークに依存するのはマクロ部分だけなので, vesting以外のフレームワーク使ってる場合でも, 考え方とかシェルは使いまわせる予感.

参考


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>