Python
Vim

結構マジメにVimのテスト環境を整えてみる(Python用)

More than 1 year has passed since last update.

概要

  • 現在に至るまで、UnitTestの実行はvim-quickrunかC-Zで戻ってからターミナル叩いてた。
  • 現状だとVimでテスト駆動開発するのにつらみがある。
  • テスト用の設定を作り込むときが来たのだ。
  • ちな実行するのはPythonのUnitTest

現状の問題点

  1. :QuickRun
    • QuickRunはテスト全体実行しかできない。と思う(テストランナーではないからね)
      • 頑張ればできるのかもしれない。
    • 時間のかかるテストとか遅いテストだと全体実行を何度もするのはつらい。一つのメソッドだけとかサクッとやりたい。
  2. ターミナル実行
    • ターミナルに戻るのはだるい。
    • ターミナルでクラス単位やメソッド単位のテストを実行するには、パッケージ階層を打たなきゃいけない。つらい。
    • QuickFixでRedに飛びたいよね。ターミナルのエラー見る→Vim戻る→ターミナルにエラー見に戻るとか愚行だよね。
  3. :make
    • makeならとりあえずなんでもできるだろう。(ザラッとできそうなことは確認したが、できるとは言っていない)
    • 設定がつらそう。builtinのunittestやらdjangotestやらnoseやらpytestやら、それぞれ設定書くのかよ。つらい。

目標

Vimのテスト環境をいい感じにする。具体的には...

  • Vim上で実行できること
  • テストクラス/メソッド単位実行が可能であること
  • QuickFixに結果出力してジャンプできること
  • 対象の言語/フレームワークが増えてもある程度対応できること
  • テスト実行オプションの指定ができること(コレができないと結局makeに戻る)
  • 非同期実行できること

調査

とりあえず。テスト用プラグインを一通り確認する。Vim Awesomeの検索フォームに対しておもむろにtestって打ち込む。
すると既存プラグインによる解決策は案外少ないということに気がつく。テスト用プラグイン自体少なかった...やっぱりmakeで解決してる人が多いのか?

vim-test

vim-testというプラグインが一番上に出てきた。
他にもpytest.vimやらvim-python-test-runnerなどあったが、要件を満たしているのは結局vim-testだけだった。

対策実施

雑な調査だがとりあえず対策開始

vim-test導入

vim-testをインスコ。英語が不自由な私の解釈だと

  • いろんな粒度に対応したテストラッパー
  • 様々な言語とフレームワークに対応
  • テスト実行だけに限って言えば依存プラグインなし
  • 設定もそんなにしなくてOK
  • 実行するランナーを選べるよ。明示的に選択しなくても自動検出するよ
  • CLIのオプション指定もできるよ

とまあ簡単導入、かつ豊富なカスタマイズってな感じのプラグインでした。ALEを思い出す。

とりあえず入れる。だーくぱわーdein.vimでどっかん。ちなみに私はプラグインは全部toml管理。

[[plugins]]
repo = 'janko-m/vim-test'

テスト実行方法は以下の5種類。詳しくはこちら

  • :TestNearest
  • :TestFile
  • :TestSuite
  • :TestLast
  • :TestVisit

適当にテスト作って実行してみる。 :TestFile実行
Screen Shot 2017-08-12 at 3.55.53.png
実行できた。しかしQuickFixはでないし、スクロールできないからエラーメッセージ全体が追えない。これでは意味がない。

QuickFix表示

vim-testのREADMEを読んでみると。どうやらQuickFixに出力したいならばテストランナーとして別プラグインが必要とのこと。んで作者的にはDispatch.vimを推奨している。

Dispatch.vim導入

調べてみたらコレがなかなかイカしてるプラグインだった。要はコンパイラを非同期実行するためのプラグインなんだが、実行過程をスクリーン分割して表示してくれる。しかも実行環境を自動検出して勝手にスクリーン分割する親切仕様。私の場合だとtmux&neovimなんだけど。勝手にtmuxのペイン作成して終了したら閉じてQuickFix出してた。

dein.vimでどっかん。再び。あとvim-test側にDispatch.vimを明示的にランナーとして設定する。

[[plugins]]
repo = 'tpope/vim-dispatch'

[[plugins]]
repo = 'janko-m/vim-test'
depends = ['vim-dispatch']
hook_add = '''
let g:test#strategy = 'dispatch'
'''

もっかい:TestFileを実行する。
Screen Shot 2017-08-12 at 4.28.18.png
無事QuickFixが表示された。しかし、errorformatがQuickFixに適用されてなかった。コレじゃジャンプできん。

ちなみに、私はここで実際に表示されるはずの出力内容よりもQuickFixの内容少なくなるという現象が発生した。原因はtmuxのバージョンが古い(たしかv2.2くらい)せいだった。2時間ぐらい悩んでv2.5にしたらあっさりなおった。

Pythonのコンパイラ設定

一応Pythonのerrorformatは以下の通り設定済みだが、どうやらコレじゃ駄目らしい。

augroup MyErrorFormat
    autocmd!
    autocmd BufNewFile,BufRead *.py
        \ setlocal errorformat=%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
augroup END

Dispatch.vimのヘルプを見てみると、どうやらerrorformatは実行するコンパイラのプラグインがないとデフォルトが適用されるらしい。

:Dispatch[!] [options] {program} [arguments]
                        Find a compiler plugin that sets 'makeprg' to
                        {program} and use its 'errorformat' to dispatch a
                        |:Make| for the given {program} and [arguments].  If
                        no compiler plugin is found, the generic format
                        %+I%.%# is used.

何のこっちゃと思って調べてみたら、それっぽいプラグインがあった。

vim-compiler-pythonの導入

vim-compiler-pythonはザラッとソースを見た感じ、:make実行時のコンパイラ設定をやっといてくれるプラグインらしい。本当は駄目だと思うけど、もう力尽きたので調べるのは後日やる。

dein.vimでどっかん。再び。

[[plugins]]
repo = 'aliev/vim-compiler-python'

もっかい:TestFileを実行する。
Screen Shot 2017-08-12 at 4.55.24.png

やっと求めてるレベルに到達した。vimrcほとんどいじってないのに、やたら疲れた。

設定まとめ

今回追加した設定はこんな感じ。正直まだテストのオプション設定やらキーバインド設定やらが残ってるけどそのへんはまた今度やる。

[[plugins]]
repo = 'tpope/vim-dispatch'

[[plugins]]
repo = 'janko-m/vim-test'
depends = ['vim-dispatch']
hook_add = '''
let g:test#strategy = 'dispatch'
'''

[[plugins]]
repo = 'aliev/vim-compiler-python'