Djangoでのテスト(パート2)–モデルマミーとDjangoのテストフィクスチャ
最後のpostで、Djangoでのテストを紹介し、ベストプラクティスといくつかの例を確認しました。 今回は、もう少し複雑な例を示し、サンプルデータを作成するためのModel Mommyを紹介します。
なぜ気にする必要があるのですか?
前回の投稿で、「https://github.com/rbarrois/factory_boy[factory_boy]、model_mommy、mockはすべて、フィクスチャまたはORMの代わりに使用されます。テストに必要なデータ。 フィクスチャとORMの両方が遅くなる可能性があり、モデルが変更されるたびに更新する必要があります。」
要約すると、Django Testing Fixturesは次の理由で問題があります。
-
モデル/スキーマが変更されるたびに更新する必要があり、
-
本当に、本当に遅いです。そして
-
ハードコーディングされたデータにより、テストが将来失敗する場合があります。
そのため、Model Mommyを使用することで、ロードが速くなり、時間の経過とともに保守がはるかに容易になるフィクスチャを作成できます。
Djangoテストフィクスチャ
最後の投稿でモデルをテストするための例を見てみましょう:
class WhateverTest(TestCase):
def create_whatever(self, title="only a test", body="yes, this is only a test"):
return Whatever.objects.create(
title=title, body=body, created_at=timezone.now())
def test_whatever_creation(self):
w = self.create_whatever()
self.assertTrue(isinstance(w, Whatever))
self.assertEqual(w.__unicode__(), w.title)
ここでは、Whatever()
オブジェクトを作成し、作成されたタイトルが期待されるタイトルと一致することを表明しました。
repoからプロジェクトをダウンロードした場合は、サーバーを起動してテストを実行します。
$ coverage run manage.py test whatever -v 2
上記のテストに合格することがわかります。
test_whatever_creation (whatever.tests.WhateverTest) ... ok
これで、毎回(退屈な!)属性ごとに新しいインスタンスを作成する代わりに、Model Mommyを使用してプロセスを合理化できます。
モデルママ
インストール:
$ pip install model_mommy
モデルがどのように見えるか覚えていますか?
class Whatever(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.title
これで、上記のテストをはるかに簡単に書き直すことができます。
from model_mommy import mommy
class WhateverTestMommy(TestCase):
def test_whatever_creation_mommy(self):
what = mommy.make(Whatever)
self.assertTrue(isinstance(what, Whatever))
self.assertEqual(what.__unicode__(), what.title)
それを実行します。 合格しましたか。
簡単だった? 引数を渡す必要はありません。
新しいモデル
もう少し複雑な例を見てみましょう。
セットアップ
新しいアプリを作成します。
$ python manage.py startapp whatevs
settings.pyファイルのInstalled_Apps
にアプリを追加します
モデルを作成します。
from django.db import models
from django.contrib.auth.models import User
from django.contrib import admin
class Forum(models.Model):
title = models.CharField(max_length=100)
def __unicode__(self):
return self.title
class Post(models.Model):
title = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
creator = models.ForeignKey(User, blank=True, null=True)
forum = models.ForeignKey(Forum)
body = models.TextField(max_length=10000)
def __unicode__(self):
return unicode(self.creator) + " - " + self.title
DBを同期します。
カバレッジレポートはどのようなものですか?
Test
テストを追加します。
from model_mommy import mommy
from django.test import TestCase
from whatevs.models import Forum, Thread
class WhateverTestMommy(TestCase):
def test_forum_creation_mommy(self):
new_forum = mommy.make('whatevs.Forum')
new_thread = mommy.make('whatevs.Thread')
self.assertTrue(isinstance(new_forum, Forum))
self.assertTrue(isinstance(new_thread, Thread))
self.assertEqual(new_forum.__unicode__(), new_forum.title)
self.assertEqual(
new_thread.__unicode__(),
(str(new_thread.forum) + " - " + str(new_thread.title)))
テストを再実行し(合格するはずです)、カバレッジレポートを作成します。
$ coverage run manage.py test whatevs -v 2
$ coverage html