django作成メソッドのリファクタリングをしたくなり、
django-noseインストールしたものの、
テスト書き始めでいきなりどうして良いのかわからなくなったので、
個人的にわからなかったポイントをメモします。

前提

django使用していて、 且つ、 以下を参考にdjango-noseインストールしていること


Tips

1. Testクラスはどこに置けば良いか?

{Django_Project_Home}/{Target_App}/tests 配下に、
__init__.py一緒に配置しました。
テストディレクトリ

__init__.py にはログ出力用途で以下の記述をしてあります。

def setup_package():
    print('')
    print(__name__, '__init__.py : setup_package() ========================================')


def teardown_package():
    print(__name__, '__init__.py : teardown_package() =====================================')

2. 標準出力にTestログを出力する。

test コマンドでテストが実行できますが、デフォルトだと test仕込んだ print結果が出力されません。

python manage.py test

-s オプションを付与することで、print結果が標準出力されます。

python manage.py test -s

settings.py NOSE_ARGS'--nocapture''--nologcapture',オプションを追加しても出力されるようになります。

NOSE_ARGS = [
    .......
    '--nocapture',
    '--nologcapture',
]

参考サイトは、NOSE_ARGS指定するの押しでしたが、真面目に実装する時は、logger使うかと思うので、
-s オプションによる実行で十分に個人的には思います。

3. テストデータを投入したい。

sqlite使用している限りはテスト実行時は、デフォルト動作で何もしなくても、
開発環境とは別のデータベースが作成されました。
データがからっぽでテスト実行時にマスタデータを投入したかったので、
以下のように実装しました。

import unittest

from django.core import management

from analyze_metrics_view.forms import get_category_choicese_relations, get_veiw_choices_relations


class TestSelectViewForm(unittest.TestCase):
    @classmethod
    def setup_class(clazz):
        print(__name__, ": setup_class")
        management.call_command('loaddata', 'fixture/initial_data.json', verbosity=0)
        pass

    # このクラスのテストケースをすべて実行した後に1度だけ実行する
    @classmethod
    def teardown_class(clazz):
        print(__name__, ": teardown_class")
        management.call_command('flush', verbosity=0, interactive=False)
        pass

django-nose機能というか、djangoコマンドを直接実行する形で、
テストデータを投入します。
initial_data作成しておく必要があります。

4. 辞書を Assert したい。

参考サイトのみ記載。どちらでもアサートできました。
副作用なかったのでassert all方がよさそうです。

5. Tupleを Assert したい。

nose.tools assert_equalsassert できました。
2次元Tuple だったのですが、普通にOKでした。

nose.tools.assert_equals(expect, result)

6. Testcase unittest.TestCase継承するかしないかで、setupメソッドの挙動が変わる。

辞書のassertため unittest.TestCase途中から継承してテストケースを作ったのですが、
setup メソッドが呼び出されなくなりました。

import unittest

class TestSelectViewForm(unittest.TestCase):
    # このクラスの各テストケースを実行する前に実行する
    def setup(self):
        print(__name__, ": setup")
        pass

    # このクラスの各テストケースを実行した後に実行する
    def teardown(self):
        print(__name__, ":teardown")
        pass

setupsetUpteardown tearDownしたら、call されるようになりました。
継承すると微妙に処理が変わるのかもしれません。
しないとどちらの記述方でも呼ばれる。。 PEP8 としては、setup`teardown が正しいっぽいので、
なるべく継承しないようにした方がいいのかな? とか思いました。
※まあ、、どっちでも良いですが。

以上です。

コメント