Hatena::Groupiphone-dev

iPhoneアプリ開発まっしぐら★ このページをアンテナに追加 RSSフィード

引っ越し後の日記はコチラです

tokoromのその他の日記

2012-05-20

vim-quickrun + GHUnit でTDD

| 04:31 | はてなブックマーク -  vim-quickrun + GHUnit でTDD - iPhoneアプリ開発まっしぐら★

VimmerなiOSプログラマの自分にとってはVim上でコーディングからユニットテストの実行/確認までできたら最高です。

ということで、vim-quickrunを使ってVim上でTDDできるようにした記録を残します。

参考記事

あらかじめインストールしておくもの

  • vim-quickrun v0.6.0dev *1
  • GHUnit *2

GHUnitについては

A-Liaison BLOG: Jenkins を iOS アプリ開発に導入してみた (GHUnit編)

が分かりやすいです。

ここを参考にCUIからテストが実行できるところまで設定をしておく必要があります。

VimでTDDするにはこのGHUnitの CUIから特定のテストを実行できる というのが重要になります。

また、CUIでGHUnitのテストを実行した場合の どこがエラーになっているのかが一目でわかりづらい というデメリットもvim-quickrunで解決します。

やったこと

  • vim-quickrunにGHUnit用のoutputterを追加
  • Objective-Cのテストコードでquickrunしたときはその追加したoutputterを使うように設定

実行結果のイメージ

■ テスト失敗

こんなかんじに失敗したテストがレッドで表示されます。

f:id:tokorom:20120521042646p:image

その後、失敗したテストの場所に自動でカーソルが移動します*3

f:id:tokorom:20120521042738p:image

■ テスト成功

こんなかんじにグリーンバーが表示されます。

f:id:tokorom:20120521042737p:image

■ ビルドエラー

おまけで、ビルドエラーのときもエラー箇所に自動でカーソルが移動します。

f:id:tokorom:20120521042739p:image

vim-quickrunに追加したoutputter

上記参考記事とvim-quickrunにはじめから入っているoutputterの quickfix.vim をベースとして以下のようなoutputterを作成しました。

let s:save_cpo = &cpo
set cpo&vim

let s:outputter = quickrun#outputter#buffered#new()
let s:outputter.config = {
\ }

function! s:outputter.finish(session)
  let data = self._result
  lclose
  if stridx(data, '** BUILD SUCCEEDED **') > 0
    " Success
    let message = matchstr(data, 'Executed .*)\.')
    if 0 == strlen(message)
      let message = '** ALL GREEN **'
    endif
    highlight GHUnitSuccess term=reverse ctermbg=darkgreen guibg=darkgreen
    echohl GHUnitSuccess | echo message | echohl None
  else
    " Failed
    try
      if data =~ '\vFile\:[^:]+Line\:'
        set errorformat=%E%.%#File:\ %f,%C%.%#Line:\ %l,%Z%.%#Reason:\ %m
        let message = matchstr(data, '\zsFailed tests.*\zeCommand ')
        if 0 == strlen(message)
          let message = '** FAILED **'
        endif
      else
        set errorformat=%f:%l:%*[^:]:\ %m
        let message = '** BUILD FAILED **'
      endif
      cgetexpr self._result
      cwindow
      cc
      for winnr in range(1, winnr('$'))
        if getwinvar(winnr, '&buftype') ==# 'ghunit'
          call setwinvar(winnr, 'quickfix_title', 'quickrun: ' .
          \   join(a:session.commands, ' && '))
          break
        endif
      endfor
      highlight GHUnitFailed term=reverse ctermbg=darkred guibg=darkred
      echohl GHUnitFailed | echo message | echohl None
    finally
    endtry
  endif
endfunction

function! quickrun#outputter#ghunit#new()
  return deepcopy(s:outputter)
endfunction

let &cpo = s:save_cpo

やっているのは大枠

  • GHUnitの実行結果が テスト成功 / テスト失敗 / ビルドエラー のどのステータスかを判断
  • その実行結果によりerrorformatを差し替え
  • 実行結果の中から表示用メッセージを拾い、テスト成功ならグリーンで、テスト失敗/ビルドエラーならレッドで表示
  • QuickFix

といったことです。

このoutputterはgithub*4に置いてあります。

.vimrc に追加した項目

最後に、これを実行するために.vimrcに追記したのが以下になります。

" ファイル名の最後がTest.mだったら objc.test というファイルタイプにする
autocmd BufWinEnter,BufNewFile *Test.m setfiletype objc.test

" quickrunの設定を初期化
let g:quickrun_config = {}
" quickrunのどのファイルタイプでも適用する設定
let g:quickrun_config['*'] = {'split': 'below'}
" ファイルタイプがobjc.testの場合、make test を実行してその結果をghunit用のoutputterで出力する設定
let g:quickrun_config['objc.test'] = {'command': 'make', 'cmdopt': 'test', 'outputter': 'ghunit'}

" Space, q でquickrunする(これは普段使っている設定にしてください)
silent! map <Space>q <Plug>(quickrun)
" Space, Space, q で今開いているテストケースだけquickrunする(ファイル名がテストクラス名と一致している前提です)
silent! map <expr> <Space><Space>q ':QuickRun -args "TEST=' . expand("%:t:r") . '"<CR>'

RanjeetRanjeet2012/08/08 18:35I tuhoght I'd have to read a book for a discovery like this!

nclhwvvnclhwvv2012/08/08 22:44NwHB8v <a href="http://bmtcwusiedal.com/">bmtcwusiedal</a>