目的
Djangoでテストを書くときに、知っているとちょっと便利かもというTipsを集めました。
前提
- テストコードの書き方については説明しません。
- この記事内では、Tipsの紹介にとどめ、詳細については記載しません。
- DRFをインストールするだけで使えるものに絞っています。
- unittestに元々備わっている機能と、djangoが拡張した機能を混ぜて紹介しています。違いが分かるように各Tips紹介の頭に目印をつけています。
バージョン
Django==4.1.9
djangorestframework==3.14.0
Tips
実行時オプション
keepdb
django
テストを実行するたびにテスト用のDBを作り直すということがなくなるので、実行時間を短縮することができます。
python manage.py test --keepdb
tag
django
テストケースにタグをつけることで、指定したタグのテストケースのみを実行することができます。
また、特定のタグを実行しないようにすることもできます。
https://docs.djangoproject.com/en/4.2/topics/testing/tools/#tagging-tests
from django.test import tag
class SampleTestCase(TestCase):
@tag("fast")
def test_fast(self):
...
@tag("slow")
def test_slow(self):
...
@tag("slow", "core")
def test_slow_but_core(self):
...
python manage.py test --tag=fast --tag=core
python manage.py test --exclude-tag=slow
test_name_patterns
unittest
-k
オプションに文字列を指定すると、その文字列を含むテストクラス、テストケースのみを実行することができます。
例えば、-k foo
にはfoo_tests.SomeTest.test_something
やbar_tests.SomeTest.test_foo
はマッチしますが、bar_tests.FooTest.test_something
にはマッチしません。
python manage.py test -k foo
settings
django
settings.pyを複数用意している場合、テストコマンド実行時だけ切り替えることができます。
python manage.py test --settings=config.settings.test
テストコード
継承元クラス
django
テストクラスの継承元には、DRFだとrest_framework.APITestCase
を指定することが多いと思います。
しかし、リクエストを送ったり、DB接続を必要としないのであればdjango.test.testcases.SimpleTestCase
で十分です。
実行速度の点でも、APIもDB接続も必要としないことを明示するという点でも、継承元クラスは書き分けた方がいいと思います。
テストクラスの継承関係は次のようになっています。
rest_framework.APITestCase
はdjango.test.testcases.TestCase
を継承しています。
https://docs.djangoproject.com/en/4.2/topics/testing/tools/#provided-test-case-classes
fixtures
django
DBを使用するテストをするとき、データはfixturesを使って入れることができます。
class SampleTestCase(APITestCase):
fixtures = ["test.json"]
fixtureはmanage.py dumpdata
で作成することができます。
詳しい作成方法については、こちらなどを参考にしてください。
- https://docs.djangoproject.com/en/4.2/ref/django-admin/#dumpdata
- https://marsquai.com/745ca65e-e38b-4a8e-8d59-55421be50f7e/05f253f8-c11b-4c91-8091-989eb2600a7b/229d6ef3-1ba3-4e16-bdd7-c5f01c6dfb12/
setup
django
, unittest
unittest.test.TestCase
には以下のメソッドが用意されています。
- setUpClass()
- テストクラスの最初に1度だけ呼ばれる。
- setUp()
- 各テストケースの最初に呼ばれる
- tearDown()
- 各テストケースの最後に呼ばれる
- tearDownClass()
- テストクラスの最後に1度だけ呼ばれる
また、django.test.testcases.TestCase
では次のメソッドが追加されています。
- setUpTestData()
- setUpClassの最後に呼ばれる
これらのメソッドをオーバーライドすることで、共通な前処理や後処理を簡潔に書くことができます。
class SampleTestCase(APITestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
...
@classmethod
def setUpTestData(cls):
...
def setUp(self):
...
TestCaseではsetUpClass()を次のようにオーバーライドしています。
トランザクションの開始、fixturesの投入、setUpTestData、をこの順で実行する。
そのため、setUpClass()をオーバーライドするときは、最初にsuper()で親のsetUpClass()を呼ぶようにします。
メッセージ
unittest
各テストケースにdocstringを書いておくと、実行時オプションで-v
を2以上にしたときに、その内容が出力されます。
class SampleTestCase(APITestCase):
def test_case(self):
"""サンプルテストケースです"""
...
---
test_case (project.app.test.SampleTestCase)
サンプルテストケースです ... ok
おわりに
ほかにもこんなTipsあるよ!といったものは是非コメントで教えていただけるとありがたいです。