更新のあったところだけテストする

Makefileとかのビルドツールを使って、変更のあったファイルあるいは、その依存関係だけをコンパイルするっていうのはよくやりますが、変更したところだけテストするようにしたプロジェクトってあまり見たことないので試しにやってみた。

Makefile.PLとかで簡単にやれるようになるとうれしいなと思いつつ、いまいち拡張のしかたよくわからないので、依存関係の解析まわりとかpythonで拡張できるらしいSConsを使ってみた。

perlのプロジェクトで、t/*.tにテストファイルがあり、lib/**/*.pmにプロジェクト用のファイルがあるという前提。ここではProjという名前空間以下のファイルだけ依存関係の解析に含める。

http://gist.github.com/345839

 
import os
import re
import glob
 
ALLOW_NAMESPACE = re.compile("Proj", re.M)
 
USE_REGEX = re.compile(r"^\s*use\s+(\S+);", re.M)
 
def perl_scan(node, env, path):
    contents = node.get_contents()
    result = USE_REGEX.findall(contents)
    baselibdir = env.GetLaunchDir() + "/lib/";
    result = [ baselibdir + '/'.join(i.split('::')) + ".pm" for i in filter(lambda x: ALLOW_NAMESPACE.findall(x), result) ]
    return result
 
def test_actions(source, target, env, for_signature):
    return "prove ./%s > %s || ( cat %s && rm %s )" % (source[0], target[0], target[0], target[0])
 
bld = Builder(generator = test_actions,
        suffix = '.tso')
 
environ = os.environ
env = Environment(ENV=environ, BUILDERS={'Test': bld})
scanner = Scanner(function = perl_scan ,skeys = ['.pm', '.t', '.pl'])
env.Append(SCANNERS = scanner)
 
for target in glob.glob('**/*.t'):
    env.Test(target)
 

テスト1ファイルごとにperlインタプリタを立ちあげるので、通常のテストに比べ、全件テストはかなり遅い。ただ変更されたモジュールに関係したテストだけが走らせられるので、ファイルの変更を監視して変更された瞬間にうんぬん、みたいなことはやりやすいのではないかなという印象。