Django で factory_boy のシード値を固定する


結論

TestCase を継承したカスタムクラスを作成して setUp() にシード値を設定する。
各アプリではカスタムクラスを継承してテストを書く。

背景

Djangoで factory_boy を使う際に、テストの再現性を担保したかった。

手順

環境

factory-boy==2.12.0

BaseTestCase クラスの定義

シード値を固定する BaseTestCase クラスを定義する。
自分は base アプリケーションを作成して、抽象クラスはそこに書くようにしている。

./base/tests.py
from django.test import TestCase
import factory.random


class BaseTestCase(TestCase):
    def setUp(self):
        factory.random.reseed_random(0)
        return super().setUp()

個別の TestCase クラスの継承

BaseTestCase クラスを継承して各テストケースを定義していく。

./user/tests.py
from base.tests import BaseTestCase

from .models import User
from .factories import UserFactory


class UserTestCase(BaseTestCase):
    def test_create_user(self):
        user = UserFactory()
        actual_user = User.objects.get(pk=user.pk)
        self.assertEqual(user, actual_user)

もちろん setUp() を定義する際は親クラスのメソッドも呼んでおく。

./user/tests.py
class UserTestCase(BaseTestCase):
    def setUp(self):
        super().setUp()
        print("initialize")

    def test_create_user(self):
        user = UserFactory()
        actual_user = User.objects.get(pk=user.pk)
        self.assertEqual(user, actual_user)

まとめ

シード値の固定により再現性を担保した状態でテストが実行できるようになった。
Djangoを前提の記事だが、Djangoに限らず通用するはず。