テストデータ作成に便利なFactoryBoyをつかってみた
はじめに
FactoryBoyというテストデータ作成ライブラリがあります.
もともとはRuby on RailsのプラグインであるFactory Girlからインスパイア(パク(ry)されてつくられたようです. http://factoryboy.readthedocs.org/en/latest/
インストールは簡単で
pip install factory_boy
だけです.
僕は,普段はadminページを開いて手動でデータを追加してたりと面倒なことをしていたのですが,FactoryBoyを使うことで,そのような手間を大幅に削減できました.
FactoryBoyをつかってみる
FactoryBoyをつかうために最低限のDjango環境を用意してあげましょう.今回も使用例を簡単なブログにしておきます.
djangoプロジェクトの立ち上げ
factoryboy_sampleというプロジェクトをつくって移動しましょう.
django-admin startproject factoryboy_sample cd factoryboy_sample
アプリを作りましょう.ここではmainとしておきます.
python manage.py startapp main
今回使うmainというappをfactoryboy_sample/settings.pyのINSTALLED_APPSの中に追記書きましょう
・・・ INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'main', ) ・・・
modelの設定
次のようなモデル設計とします.(このあたりは前回の記事を流用…)
- BlogModel
- 日付(date: DateTimeField)
- タイトル(title: CharField)
- 内容(message: TextField)
このモデルを実際に反映していきます. main/models.pyを開き,次のように編集してください.
from django.db import models class BlogModel(models.Model): date = models.DateTimeField() title = models.CharField(max_length=256) message = models.TextField()
これでmodelの環境は整いました. Datetimeの初期値は無くても良いですが,一応default値として現在時刻を入れておきました
FactoryBoy
今回の本題を書いていきます.
main/factory.pyというファイルをつくりましょう.
touch main/factory.py
このファイルの中に次のようなコードを書いてください.
from factory import DjangoModelFactory, lazy_attribute from main.models import BlogModel from factory.fuzzy import FuzzyText import random import datetime class BlogModelFactory(DjangoModelFactory): class Meta: model = BlogModel date = datetime.datetime.now() title = lazy_attribute(lambda o: random.choice(['ham', 'spam', 'egg'])) message = FuzzyText()
解説するとModelFormのような使い方で定義ができます. class Metaの中にあるmodel変数に使うModelを指定します. あとはModelに指定されている,各値をどのような内容にするか設定するというものです.
異なるテストデータを入力するための便利な機能として,FuzzyとLazyがあります.Fuzzyは勝手にテキストを生成してくれるなど,自動でテストデータを生成するときに便利です. lazyはrandomで出した結果を反映させたいときに使います.詳しいことはわからないのですが,lazy_attributeを使わずにrandom.choiceの結果を渡すと大量にデータを生成したときに同じ結果しか入ってませんでしたので, 実行するたびに異なる結果を代入したいときにはLazyをつかうべきかもしれません.
確かめる
今回は確かめる手段としてdjangoのshellをつかってみます.
まずはその前にmakemigrationsとmigrateを実行しましょう.
python manage.py makemigrations python manage.py migrate
python manage.py shell
次のような内容を打つことでデータを自動で1件生成してくれるはずです.
from main.factoryboy import BlogModelFactory BlogModelFactory()
次のようにcreate_batchメソッドに件数を打つとその件数分入ります(ここでは10件).
from main.factoryboy import BlogModelFactory BlogModelFactory.create_batch(10)
では本当に中身があるか見てみましょう.おそらく1件+10件表示されるはずです.
from main.models import BlogModel for x in BlogModel.objects.all(): print('date={0}, title={1}, message={2}'.format(x.date, x.title, x.message))
titleについては予め決めた範囲から値をランダムに取り出してますし,messageについては出鱈目な文字列が入っていると思います.
date=2015-01-24 18:00:46.741512+00:00, title=egg, message=gTwpefYyxfIJ date=2015-01-24 18:00:46.741512+00:00, title=spam, message=UotYBXwLooXL date=2015-01-24 18:00:46.741512+00:00, title=ham, message=vHjJYITVvFBS date=2015-01-24 18:00:46.741512+00:00, title=egg, message=oMOOtsFnrGBL date=2015-01-24 18:00:46.741512+00:00, title=egg, message=QhlKBXLsraQL date=2015-01-24 18:00:46.741512+00:00, title=egg, message=khQxmqzpoeOC date=2015-01-24 18:00:46.741512+00:00, title=egg, message=lFRsLoVFsHoO date=2015-01-24 18:00:46.741512+00:00, title=spam, message=lheWOYPpRiJR date=2015-01-24 18:00:46.741512+00:00, title=egg, message=kCRhCPSdmgbE date=2015-01-24 18:00:46.741512+00:00, title=egg, message=hElOIWYlJAqz date=2015-01-24 18:00:46.741512+00:00, title=ham, message=GrEFddntNXyQ
まとめ
Factoryboyでテストデータを自動生成してみた.