5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Django Rest Framework(DRF)のテストを書くときのTips

Posted at

目的

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

test.py
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_somethingbar_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.APITestCasedjango.test.testcases.TestCaseを継承しています。
https://docs.djangoproject.com/en/4.2/topics/testing/tools/#provided-test-case-classes
その他のテストクラス

fixtures

django

DBを使用するテストをするとき、データはfixturesを使って入れることができます。

test.py
class SampleTestCase(APITestCase):
    fixtures = ["test.json"]

fixtureはmanage.py dumpdataで作成することができます。
詳しい作成方法については、こちらなどを参考にしてください。

setup

django, unittest

unittest.test.TestCaseには以下のメソッドが用意されています。

setUpClass()
テストクラスの最初に1度だけ呼ばれる。
setUp()
各テストケースの最初に呼ばれる
tearDown()
各テストケースの最後に呼ばれる
tearDownClass()
テストクラスの最後に1度だけ呼ばれる

また、django.test.testcases.TestCaseでは次のメソッドが追加されています。

setUpTestData()
setUpClassの最後に呼ばれる

これらのメソッドをオーバーライドすることで、共通な前処理や後処理を簡潔に書くことができます。

test.py
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以上にしたときに、その内容が出力されます。

test.py
class SampleTestCase(APITestCase):
    def test_case(self):
        """サンプルテストケースです"""
        ...

---
test_case (project.app.test.SampleTestCase)
サンプルテストケースです ... ok

おわりに

ほかにもこんなTipsあるよ!といったものは是非コメントで教えていただけるとありがたいです。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?