最近,我了解了,并希望在我的Django项目中开发一个新的应用程序时尝试一下。我一直在读用Python进行测试驱动开发,这很好。然而,我有时会发现书中的示例(做列表)太简单了--例如,当介绍了测试模型。时,作者有一个测试来创建对象,保存它们,然后从数据库中提取对象来检查它们的值。当然,当您的模型只有一个ModelField时,这很容易。
但是当您的模型有20 ModelFields时呢?您是否应该有一个测试来创建一个对象,并包含它的所有字段,然后保存该对象,然后检查每个字段的值?对每个字段进行单独的测试是否更好?
在我的具体案例中,我有一个模型,它有大约5个必需字段,然后还有大约15个可选字段。我现在的想法是首先在我的TestCase类中有一个函数,它用默认字段创建这个模型的一个对象。然后,我将进行一个测试,以确保该对象正常保存,然后对每个单独的可选字段进行另一个测试。似乎有很多测试,但是很多小测试不是比一个大测试更好吗?
感谢你的洞察力!
发布于 2014-05-22 12:31:06
我是那本书的作者。我的意思是,该测试更多地是作为Django ORM的介绍,而不是作为最佳实践的演示,我当时试图解释这一点,但我认为有些混淆是不可避免的。我会想一想如何以不同的方式呈现事物。
无论如何,如果您跳过书中的几章之后,我将向您展示如何将测试简化为更好的实践。
您是否测试基本Django模型取决于您--有些人会说测试声明性语法是过头了,另一些人则会说一个简短的测试作为占位符是好的。这里有一个你可能会用到的:
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author)
ISBN = models.CharField(max_length=35)
abstract = models.TextField()
class BookTest(TestCase):
def test_defaults(self):
book = Book()
self.assertEqual(book.title, '')
self.assertEqual(book.author, None)
self.assertEqual(book.ISBN, '')
self.assertEqual(book.abstract, '')所以这是占位符。它鼓励您添加更多的测试,如果您开始引入更复杂的字段,比如publication_date字段,它的默认值为datetime.today() + one_month,这可能需要进行一些测试,以确保正确。有一个占位符可以降低后续测试的门槛。其他人会告诉你这太过分了。你必须找到你自己的平衡。
有一件事是被广泛接受的,那就是你一定要测试行为。因此,如果您的模型有一个自定义方法:
class Book(models.Model):
# [...]
def is_available(self):
return self.pub_date < datetime.today() and Stock.objects.filter(book=self).count() > 0那么,对此进行某种测试肯定是个好主意。
发布于 2014-05-21 16:55:57
这就是模范工厂会有很大帮助的地方。有两个流行的模块提供它:
model_mommyfactory_boy我个人使用过factory_boy,发现它很容易使用。
基本上,您定义了一个具有默认值的工厂:
class UserFactory(factory.Factory):
class Meta:
model = models.User
first_name = 'John'
last_name = 'Doe'
admin = False然后,如果需要,可以使用使用工厂和重写字段值。它还支持序列、懒惰属性和其他有用的特性来生成数据。
谈到您的特定任务,尽量不要测试django实际测试的内容。例如,不需要测试required参数是否有效。测试与操纵模型有关的自定义模型逻辑。
同时,A Guide to Testing in Django也是一个很好的读物。
希望这能有所帮助。
发布于 2014-05-21 17:41:11
为什么要测试值的保存和加载到数据库?这是Django的责任。Django有一整套测试,详细检查其数据库层是否正常工作。绝对没有理由检查任何字段的基本行为,更不用说所有字段了。
您的单元测试是针对您的逻辑的:自定义方法、视图、模板标记。它们并不适用于Django默认提供的逻辑。
https://stackoverflow.com/questions/23789199
复制相似问题