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
は作成しておく必要があります。
-
参考サイト(
initial_data
の作成)
Providing initial data for models | Django documentation | Django -
参考サイト(テスト中のデータ投入)
How to load fixtures only once in django unit tests ? - Stack Overflow
4. 辞書を Assert
したい。
参考サイトのみ記載。どちらでもアサートできました。
副作用なかったのでassert all
の方がよさそうです。
- 参考サイト
Pythonでdictを比較してassertしたい - Life is Really Short, Have Your Life!! python - Assert that two dictionaries are almost equal - Stack Overflow
5. Tupleを Assert
したい。
nose.tools
の assert_equals
でassert
できました。
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
setup
をsetUp
、teardown
を tearDown
にしたら、call
されるようになりました。
継承すると微妙に処理が変わるのかもしれません。
しないとどちらの記述方でも呼ばれる。。 PEP8 としては、setup
、`teardown が正しいっぽいので、
なるべく継承しないようにした方がいいのかな? とか思いました。
※まあ、、どっちでも良いですが。
以上です。
コメント