PythoscopeでPythonのユニットテストのひな形を自動生成する

最近、テストコードを書いていて、ふとPythonのテストコードを自動的に
生成できる方法はないものかと思い立ったので、いろいろと調べた結果
Pythoscopeというツールを発見したのでメモします。

Pythoscopeとは

Pythoscopeとはユニットテストのひな形を生成するツールです。

また特徴として以下の3つが挙げられます。

  • unittestnoseに対応
  • 各関数ごとにテストを生成してくれる
  • モジュール内でテストされていない箇所があった場合\
    その箇所のテストを追加してくれる。

インストール

2.x系の場合、pip install pythoscopeで問題ないのですが、3.x系の場合
はうまく行きません。筆者の開発環境は3.x系なので非常に悩みましたが
とりあえず、virtualenvwrapperで2.x系の実行環境を用意することで我慢しました。

テストコードの生成

まず、テストを生成したいモジュールのあるディレクトリで\

pythoscope --init

とコマンドします。そうすると.pythoscopeというディレクトリが生成され
テストを生成する準備が整います。 次にモジュールtarget.pyについて

pythoscope -t nose target.py

とコマンドすることでテストを生成することが出来ます。

## target.py

class Target(object):
    def __init__(self, a): 
        self.a = a 

    def f(self):
        return '%s' % self.a

def func():
  return None

## tests/test_tmp.py from nose import SkipTest from nose.tools import assert_equal class TestTarget: def test___init__(self): # target = Target(a) raise SkipTest # TODO: implement your test here def test_f(self): # target = Target(a) # assert_equal(expected, target.f()) raise SkipTest # TODO: implement your test here class TestFunc: def test_func(self): # assert_equal(expected, func()) raise SkipTest # TODO: implement your test here

Pythoscopeで生成したテスト(nose形式)はSkipTestを投げてくれるので
テストの抜け漏れに気づくことが出来ます。しかし、本来テストしたくない
場所からもテストが生成され、SkipTestが投げられます。
このままではSkipTestまみれになり、本当にテストを書くべき抜け漏れに
気づくことができなくなってしまいます。そこで
テストしたくない、もしくはする必要のない場所にテストが生成された場合は
SkipTestを投げずにあえて、passするように書き換えるようにすることで
ご利益を享受できるようになります。

今後の展望

gulp-watch
watchdogguard
などでファイルの編集を監視しコードを編集すると同時に、テストの雛形を自動生成させてみるのも
面白いかもしれません。

結論

ここまでPythoscopeのことを褒めてきましたが

  • テストをする必要のない関数のひな形も生成してしまう
  • さらにそれを消したとしても、蘇る
  • SkipTestpassで回避した場合、テストが成功しているとカウントされる
  • テストを書いてから実装するというTDD本来の方式から外れている

等のデメリットもあるため、実際に今後の展望で述べたような運用するのは厳しいです。また、レガシーコードのテストを生成するにしても上記のようなデメリットが付きまとってくるので、まだ実用性に欠けるというのが筆者の結論です。