Help us understand the problem. What is going on with this article?

Vim PluginでもUnit testを回したい!

Vim PluginでもUnit testを回したい!

こんにちは、IKです。
ところで皆さんは毎日Vim scriptを書き、Vim Pluginを公開していると思いますが、
Unit test、したくないですか...?
したいと思ったそこの貴方が今回の対象です!!!

この記事を書く際に、@kamyknさんのspelunker.vimを参考にしています。

用意するもの

以下の3点です

(今回はCircieCIを使った方法を書きます)

テスト導入

今回は自分の作成したPluginにUnit testを導入したので、自分のPluginをベースにUnit testの導入フローを紹介したいと思います。

以下のような、Vimで天気をみるためのPluginのためのUnit testです。

https://github.com/kazukazuinaina/Weather.vim

Untitled.gif

ディレクトリ構造

.
├── .circleci
│   ├── .vimrc
│   └── config.yml
├── .github
│   └── ISSUE_TEMPLATE
│       ├── ISSUE_TEMPLATE.md
│       └── bug_report.md
├── .gitignore
├── LICENCE
├── README.md
├── Weather.gif
├── autoload
│   ├── Weather
│   │   ├── city
│   │   │   ├── Hiroshima.vim
│   │   │   ├── Hukuoka.vim
│   │   │   ├── Kyoto.vim
│   │   │   ├── Nagoya.vim
│   │   │   ├── Osaka.vim
│   │   │   ├── Sapporo.vim
│   │   │   ├── Sendai.vim
│   │   │   ├── Shiga.vim
│   │   │   └── Tokyo.vim
│   │   ├── returncity.vim
│   │   ├── test
│   │   │   ├── test_popup.vim
│   │   │   └── test_status.vim
│   │   └── test.vim
│   └── Weather.vim
├── doc
│   └── Weather.txt
└── plugin
    └── Weather.vim

テストコードに関するスクリプトは、test ディレクトリ内にあるtest_status.vim
Weatherディレクトリ内にあるtest.vimです。

簡単にこのスクリプトについて紹介しておきます。

  • test.vim

これは、testディレクトリに置かれた単体テスト用のスクリプト群をまとめて実行するためのファイルです。

  • test_status.vim

これは、apiを叩いた際にhttp statusが正しく返って来ているかをtestするためのスクリプトファイルです。

testコードカキコ

じゃあ実際にtestを書いていきましょう。

test_status.vim

" test_status.vim

let s:dir = expand('<sfile>:h:h') . '/city'
let s:city_data = map(glob(expand(s:dir) . '/*.vim', 1, 1), 'fnamemodify(v:val, ":t:r")')

function! Weather#test#test_status#run()

for i in s:city_data
  let l:id = Weather#returncity#return(i)
  let l:res = webapi#http#get('http://weather.livedoor.com/forecast/webservice/json/v1?city='.id)
  echo i . " status:" .  l:res.status
  " l:res.statusは文字列だから10進数に変換
  call assert_equal(200, str2nr(l:res.status, 10))
endfor

endfunction

test_status.vimは、cityディレクトリにある都市のファイル名を抜き出し、その都市に対応するidを指定してapiをgetで叩き、それをassert_equalで評価するためのスクリプトになります。
今回のケースだと、call assert_equal(200, str2nr(l:res.status, 10))の部分がそれに当たり、これはwebapi#http#get('http://weather.livedoor.com/forecast/webservice/json/v1?city='.id)で返ってきたhttpレスポンスが200ならヨシ!、そうでないならダメと言う感じになります。

assert_equalについてはこちらに記事がが参考になると思います!

https://thinca.hatenablog.com/entry/20151203/1449076256

test.vim

" test.vim

scriptencoding utf-8

let s:save_cpo = &cpo
set cpo&vim

function! Weather#test#run()
  " v:errorsを初期化する
  let v:errors = []
  call Weather#test#test_status#run()
  if len(v:errors) >= 1
    echo v:errors
    " error exit
    execute 'cq!'
  endif
echo 'test success'
execute 'qall!'
endfunction

let &cpo = s:save_cpo
unlet s:save_cpo

test.vimは、test_status.vimで実行したassert_equalの結果を返し、Vimを終了させるようなスクリプトになっています。

もし、assert_equalを実行し、問題なければ:qa!でVimを終了、問題があれば:cq!でVimを終了させるスクリプトになっています。

circle ciの設定

testが書けたらあとはcircle ciに丸投げしちゃいましょう!!

version: 2
jobs:
  build:
    docker:
      - image: centos:7

    working_directory: ~/project

    steps:
      - checkout

      - run:
          name: ls
          command: ls -la

      - run:
          name: yum
          command: yum update -y && yum install make gcc ncurses-devel ssh git -y

      - run:
          name: Build latest Vim
          command: git clone https://github.com/vim/vim.git && (cd vim && make && make install)

      - run:
          name: Vim version
          command: vim --version

      - run:
          name: Install webapi-vim
          command: git clone https://github.com/mattn/webapi-vim

      - run:
          name: write .vimrc
          command: mv ~/project/.circleci/.vimrc ~/.vimrc

      - run:
          name: check path
          command: ls -la && pwd

      - run:
          name: Unit test
          command: vim +":call Weather#test#run()"

これで、circle ciくんが自動でVimを起動し、テストを動かし、Vimを終了するところまで自動で回してくれます!
自動化って素晴らしい!!

やっていることとしては、

  1. yumをupdate
  2. 必要なpackage群をインストール
  3. Vimをビルド
  4. pluginをインストール
  5. vimrcをホームディレクトリに配置(もっといい方法あると思います)
  6. Vimを起動し、上記のtest用の関数を呼び出す

これがtest用のvimrcです

scriptencoding utf-8
set encoding=utf-8
syntax enable
set runtimepath+=~/project
set runtimepath+=~/project/webapi-vim

スクリーンショット

テストが成功した図

スクリーンショット 2019-11-22 16.45.15.png

テストが失敗して絶望している図

スクリーンショット 2019-11-26 9.34.57.png

最後に

どうでしたか?
これでより豊かなVim lifeが送れることでしょう!
Happy Vimming!!

次の@aiya000さんの記事にも期待です!!

参考文献

https://thinca.hatenablog.com/entry/20151203/1449076256
https://github.com/kamykn/spelunker.vim

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away