Vim の "make test" を読み解く 第 2 回 (scripttests 概要)

[前回](https://qiita.com/mnishz/items/865751bedd1f7d28a740) に引き続き、src/Makefile の中身を見ていきます。今回は `make test` で実行されるターゲットのうち、一番最初に実行されてかつ一番重要と思われる scripttests についてです。中身の大部分は Vim 本体の機能のテストです。

# src/Makefile, scripttests
```Makefile:src/Makefile
scripttests:
	$(MAKE) -f Makefile $(VIMTARGET)
	if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
		cd $(PODIR); $(MAKE) -f Makefile check VIM=../$(VIMTARGET); \
	fi
	-if test $(VIMTARGET) != vim -a ! -r vim; then \
		ln -s $(VIMTARGET) vim; \
	fi
	cd testdir; $(MAKE) -f Makefile $(GUI_TESTTARGET) VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
```
まず一番初めに Vim 自身の make を行っています。あらかじめ make してあった場合は一瞬で終わるはずです。

次に src/po に入って、翻訳された Vim message (?) の内容に問題がないかを確認しています。実際に日本語の例を見てみると雰囲気が分かるかと思いますが、オリジナルの各 msgid に対しそれぞれの言語の訳が存在しています。この訳の形式が間違っていないかのチェックのようです。機会があれば別途詳細を調べる予定。

```text:src/po/ja.po
msgid "Overwrite existing file \"%s\"?"
msgstr "既存のファイル \"%s\" を上書きしますか?"
```
その次は `make` で出来上がるバイナリ名が "vim" でないときのために、symbolic link を作成しています。configure の `--with-vim-name` オプションでバイナリ名を変えられるみたいですが、そんな需要があるのか？ -> `:help 90.3` に記述がありました。新しいバージョンをしばらくの間試すときに、別名でビルドするためのオプションのようです。

最後に src/testdir に移動して、さらに make の処理を続けます。

# src/testdir/Makefile, default
```Makefile:src/testdir/Makefile
default: nongui

nongui:	nolog $(SCRIPTS_FIRST) $(SCRIPTS) newtests report

nolog:
	-rm -f test.log messages

newtests: newtestssilent
	@/bin/sh -c "if test -f messages && grep -q 'SKIPPED\|FAILED' messages; then cat messages; fi"

newtestssilent: $(NEW_TESTS)

# New style of tests uses Vim script with assert calls.  These are easier
# to write and a lot easier to read and debug.
# Limitation: Only works with the +eval feature.
RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(VIMPROG) -f $(GUI_FLAG) -u unix.vim

.vim.res: writevimcmd
	@echo "$(VIMPROG)" > vimcmd
	@echo "$(RUN_VIMTEST)" >> vimcmd
	$(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim $(REDIR_TEST_TO_NULL)
	@rm vimcmd

report:
	@echo
	@echo 'Test results:'
	@/bin/sh -c "if test -f test.log; \
		then cat test.log; echo TEST FAILURE; exit 1; \
		else echo ALL DONE; \
		fi"
```
```Makefile:src/testdir/Make_all.mak
# Test targets that use runtest.vim.
# Keep test_alot*.res as the last one, sort the others.
# test_largefile.res is omitted, it uses too much resources to run on CI.
NEW_TESTS_RES = \
	test_arabic.res \
	test_arglist.res \
	test_assert.res \
	    :
```
GUI でなければ `default `の `nongui` が実行されます。`nolog` は単純にログの削除ですね。どうやらテストを実行すると `test.log` と `messages` というファイルが作られるようです。

`$(SCRIPTS_FIRST)` は一番最初に実行される script で、テストが実行可能な環境 (状況？) か調べる script のようです。また `$(SCRIPTS)` はいわゆる `old-style-testing` で、今後追加されることはあまりなくて `new-style-testing` への移行も行われていると聞きました。こちらの 2 つについては今後機会があれば詳細を見ていきます。今回はスキップ。

`newtests` -> `newtestssilent` -> `$(NEW_TESTS_RES)` と進みます。`$(NEW_TESTS_RES)` は src/testdir/Make_all.mak にあって、`make test` で得られるべき出力結果 `test_*.res` の一覧が定義してあります。`.vim.res` に定義してあるコマンドによってテストスクリプトが実行され、これらの出力結果が得られます。ここの詳細は次回以降のトピックにする予定です。ところで `writevimcmd` ってなんでしょう。`.vim.res` の依存ターゲットのようですが、何を指しているのか分からなかった。。。 (2019/3/10追記、修正ミスのように思えたので、削除する PR を送ったら無事マージされました。) ちなみにここのコメントにあるように、test_largefile は `make test` の対象からは外されているようです。

`newtests` では、messages 内に SKIPPED もしくは FAILED があると messages を表示しています。私が実行した結果では FAILED こそありませんでしたが、SKIPPED は 10 個ほどありました。(2019/3/10追記、[第 3 回](https://qiita.com/mnishz/items/957f52c71884fa055dd9) で SKIPPED についての説明が出てきました。)

`report` で前回言及した ALL DONE と TEST FAILURE の表示を行っています。これを見ると test.log というファイルが存在しているとスクリプトテストとしては失敗ということになるようです。

第 2 回はここまで。