Python.use(better)「テストケースを生成するコード」を生成するコード
Python.use(better)
「テストケースを生成するコード」を生成する
《Jython2.5.0》
《著》小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/25 ● 第2版♪2004/06/01 ● 第3版♪2009/02/28
■ 概要
♪スタッフ研修用のセミナー教材(2003)に加筆(再構成)して、公式マニュアルの補足情報を提供します。
■ 関連記事
25.2. doctest — Test interactive Python examples ★★
「《テストケースを生成するコード》を生成するコード」を記述する方法を紹介します。
ここでも、基本的なアプローチとして「共通項を抽出してひとつにまとめる」リファクタリングの定石に従います。前述したテストケース ex_1/ex_2 には、共通する中にいくつかの相違点があります。
def ex(testcase): for e in range(testcase+1): print ">>> #","-"*20,"ex_%s"%e eval("ex_%d()"%e) print
まず、テストの対象となるメソッド find/index の違いがあります。次に、例外 ValueError を生成するかどうかの違いがあります。そこで、これらの違いを捨象した、抽象表現に変換します。それには、メタプログラミングの基本ツールとして組み込み関数 eval/compile を利用します。
メソッド名の違いは、実引数を介して実行時に確定させます。例外処理については、ValueError を生成する可能性とは無関係に、つねに try/except ブロックを用意します。
def examples(): print ">>> #","-"*20,"examples" for s1,s2 in [ ('ABC@', '"ABC".find(%r)' ), ('ABC@', '"ABC".index(%r)' ), ('ABC@', '"ABCABA".count(%r)'), ]: X = ex_(s1, s2) eval(compile(X,"","exec")) def ex_(s1, s2): return '''def ex(): for e in %r: X = '%s'%%e print ">>> try:" print "... ",X print "... except ValueError,e:" print "... print e" try: eval(compile(X,"","single")) except ValueError,e: print e ex()'''%(s1,s2)
これを実行すると、次のような出力が得られます。
>>> examples()
>>> # -------------------- examples
>>> try:
... "ABC".find('A')
... except ValueError,e:
... print e
0
>>> try:
... "ABC".find('B')
... except ValueError,e:
... print e
1
>>> try:
... "ABC".find('C')
... except ValueError,e:
... print e
2
>>> try:
... "ABC".find('@')
... except ValueError,e:
... print e
-1
>>> try:
... "ABC".index('A')
... except ValueError,e:
... print e
0
>>> try:
... "ABC".index('B')
... except ValueError,e:
... print e
1
>>> try:
... "ABC".index('C')
... except ValueError,e:
... print e
2
>>> try:
... "ABC".index('@')
... except ValueError,e:
... print e
substring not found in string.index
>>> try:
... "ABCABA".count('A')
... except ValueError,e:
... print e
3
>>> try:
... "ABCABA".count('B')
... except ValueError,e:
... print e
2
>>> try:
... "ABCABA".count('C')
... except ValueError,e:
... print e
1
>>> try:
... "ABCABA".count('@')
... except ValueError,e:
... print e
0