noseまとめの2回目。今回は、テストの前処理・後処理について整理しました。

ユニットテストにおける前処理・後処理とは?

まずは一般的な話ですが、ユニットテストは、モジュールごとに独立して動作させる必要があります。

どういうことかと言いますと...

  • テストを実行させるために、事前条件を設けてはいけない。(例: Bというテストを動作させるためには、Aというテストを事前に実行させる必要がある。)
  • また、テストの実行が後の処理に影響を与えてはいけない。(例: Aというテストを実行した結果ゴミが残り、Bというテストの実行に失敗する。)

このように、良いテストを実装するためには、テストの準備・後片付けが必要となります。そして、主要のユニットテスト・フレームワークには、テストの前処理・後処理を実行させる仕組みが用意されています。

noseの前処理・後処理

noseで前処理・後処理を行うためには、setup及びteardownメソッドを実装します。noseは、メソッド名から自動的に前処理・後処理を判別し、適切なタイミングで実行してくれます。

関数の場合

def setup():
    '''テストの前処理'''
    pass

def teardown():
    '''テストの後処理'''
    pass

クラスの場合

class TestClass(object):
    def setup():
        '''テストの前処理'''
        pass

    def teardown():
        '''テストの後処理'''
        pass

前処理・後処理の実行順序

どのようなタイミングでsetup/teardownが呼び出されるかを理解することは、テストを実装する上で非常に大切になります。実際に、以下のコードを実行させて検証してみます。

[test_sample.py]

def setup():
    print 'setup --- function'


def teardown():
    print 'teardown --- function'


def test_method_01():
    print 'test_method_01 --- function'


def test_method_02():
    print 'test_method_02 --- function'


class TestClass():
    def setup(self):
        print 'setup --- instance method'

    def teardown(self):
        print 'teardown --- instance method'

    def test_method_01(self):
        print 'test_method_01 --- instance method'

    def test_method_02(self):
        print 'test_method_02 --- instance method'

以下は、実行結果です。

setup --- function
setup --- instance method
test_method_01 --- instance method
teardown --- instance method
setup --- instance method
test_method_02 --- instance method
teardown --- instance method
test_method_01 --- function
test_method_02 --- function
teardown --- function

このような挙動になりますので、

  • 前処理・後処理を繰り返し実行させる必要がある ... クラスで実装
  • 前処理・後処理を繰り返し実行させる必要はない ... 関数で実装

と設計することが出来るかなと思います。



Comments

comments powered by Disqus