Make組ブログ

Python、Webサービスや製品開発、ライブラリー開発についてhirokikyが書きます

factory-boyとDjangoでテストを書くときにファイルをうまく使う

ORMってファイルが入ると途端にめんどくさくなるよね。

まして単体テストで都度物理的なファイルを扱ったりするのはもうめんどくさすぎます。 でも factory-boy を使えばDjangoのFileFieldやImageFieldも楽に使えます。

バージョン

factory-boy==2.11.1 でやってます。

使い方

こんな感じで ImageField を持ったモデルで説明します。

from django.db import models


class Book(models.Model):
    cover_image = models.ImageField("カバー画像", ...)

factory-boyをこんな感じで書きます。 factory.django.ImageField を設定しておきます。

import factory


class BookFactory(factory.django.DjangoModelFactory):
    cover_image = factory.django.ImageField()

    class Meta:
        model = models.Book

そうすれば cover_image__ のように __ に続いて指定できます。 この例だと自動で作る画像の色とファイルの名前、サイズ、画像の拡張子を指定しています。

        book = BookFactory(
            cover_image__color='green',
            cover_image__format='PNG',
            cover_image__height=10,
            cover_image__width=10,
            cover_image__filename='test.png',
        )

いちいち物理的なファイルやら django.core.files.base.ContentFile やらも使わずに書けて便利。 この factory.django.ImageField__init__ に渡せる引数を、 __ 経由で渡せるようです。

Using factory_boy with ORMs — Factory Boy latest documentation

factory.django.FileField の場合は __data でバイナリーを指定できます。 すごく便利。

factory-boyについてはPythonプロフェッショナルプログラミングの14章にも書いたのでぜひ読んでみてください。

Pythonプロフェッショナルプログラミング 第3版

Pythonプロフェッショナルプログラミング 第3版