Django:优化违反DRY的测试
Django: optimize test that violates DRY
被测机型为
class A(models.Model):
""" model A"""
name = models.CharField(max_length=50, unique=True)
slug = AutoSlugField(max_length=265, unique=True, populate_from='name')
link = models.URLField(blank=True)
class Meta:
verbose_name = 'Model A'
def __unicode__(self):
return self.name
class B(models.Model):
""" model B"""
name = models.CharField(max_length=50, unique=True)
slug = AutoSlugField(max_length=265, unique=True, populate_from='name')
link = models.URLField(blank=True)
class Meta:
verbose_name = 'Model B'
def __unicode__(self):
return self.name
给定模型的简单测试,
class TestA(TestCase):
""" Test the A model """
def setUp(self):
self.name = 'A'
self.slug = 'a'
self.object = A.objects.create(name=self.name)
def test_autoslug_generaton(self):
""" test automatically generated slug """
assert self.object.slug == self.slug
def test_return_correct_name(self):
""" test the __unicode__() method """
assert self.object.__unicode__() == self.name
class TestB(TestCase):
""" Test the A model """
def setUp(self):
self.name = 'B'
self.slug = 'b'
self.object = B.objects.create(name=self.name)
def test_autoslug_generaton(self):
""" test automatically generated slug """
assert self.object.slug == self.slug
def test_return_correct_name(self):
""" test the __unicode__() method """
assert self.object.__unicode__() == self.name
这里的测试违反了 DRY,因为测试只是更改模型的副本。我该如何重构测试,因为它不违反 DRY?
DRY- Dont Repeat Yourself, a software development philosophy which aims at reducing redundancy and code repetition.
谢谢。
正如@mevius评论中指出的答案中提到的那样,多重继承是一种方式。为重复的测试方法创建一个Mixin,在实际测试中实现setUp
和tearDown
即可 类:
class MixinAB(object):
def test_autoslug_generaton(self):
""" test automatically generated slug """
assert self.object.code == self.slug
def test_return_correct_name(self):
""" test the __unicode__() method """
assert self.object.__unicode__() == self.name
class TestA(MixinAB, TestCase):
""" Test the A model """
def setUp(self):
self.name = 'A'
self.slug = 'a'
self.object = A.objects.create(name=self.name)
建议的重复和 schwobaseggl 的答案解决了你的高级问题,但可能还有另一种方法可以解决,我认为这对 DRY 更好。目前你有两个 99% 相同的模型。我希望其中一些是为了让您的问题更加集中,但假设您的 "real" 模型中存在大量重叠,那么您已经无法避免重复自己。我建议考虑重构 A 和 B 以继承基本模型(参见 https://docs.djangoproject.com/es/1.9/topics/db/models/#abstract-base-classes)。然后,您可以为重构到基础(可以使用 A 或 B 的实例)的通用功能创建一个测试用例,然后为 A 和 B 的独特部分分离测试用例。
被测机型为
class A(models.Model):
""" model A"""
name = models.CharField(max_length=50, unique=True)
slug = AutoSlugField(max_length=265, unique=True, populate_from='name')
link = models.URLField(blank=True)
class Meta:
verbose_name = 'Model A'
def __unicode__(self):
return self.name
class B(models.Model):
""" model B"""
name = models.CharField(max_length=50, unique=True)
slug = AutoSlugField(max_length=265, unique=True, populate_from='name')
link = models.URLField(blank=True)
class Meta:
verbose_name = 'Model B'
def __unicode__(self):
return self.name
给定模型的简单测试,
class TestA(TestCase):
""" Test the A model """
def setUp(self):
self.name = 'A'
self.slug = 'a'
self.object = A.objects.create(name=self.name)
def test_autoslug_generaton(self):
""" test automatically generated slug """
assert self.object.slug == self.slug
def test_return_correct_name(self):
""" test the __unicode__() method """
assert self.object.__unicode__() == self.name
class TestB(TestCase):
""" Test the A model """
def setUp(self):
self.name = 'B'
self.slug = 'b'
self.object = B.objects.create(name=self.name)
def test_autoslug_generaton(self):
""" test automatically generated slug """
assert self.object.slug == self.slug
def test_return_correct_name(self):
""" test the __unicode__() method """
assert self.object.__unicode__() == self.name
这里的测试违反了 DRY,因为测试只是更改模型的副本。我该如何重构测试,因为它不违反 DRY?
DRY- Dont Repeat Yourself, a software development philosophy which aims at reducing redundancy and code repetition.
谢谢。
正如@mevius评论中指出的答案中提到的那样,多重继承是一种方式。为重复的测试方法创建一个Mixin,在实际测试中实现setUp
和tearDown
即可 类:
class MixinAB(object):
def test_autoslug_generaton(self):
""" test automatically generated slug """
assert self.object.code == self.slug
def test_return_correct_name(self):
""" test the __unicode__() method """
assert self.object.__unicode__() == self.name
class TestA(MixinAB, TestCase):
""" Test the A model """
def setUp(self):
self.name = 'A'
self.slug = 'a'
self.object = A.objects.create(name=self.name)
建议的重复和 schwobaseggl 的答案解决了你的高级问题,但可能还有另一种方法可以解决,我认为这对 DRY 更好。目前你有两个 99% 相同的模型。我希望其中一些是为了让您的问题更加集中,但假设您的 "real" 模型中存在大量重叠,那么您已经无法避免重复自己。我建议考虑重构 A 和 B 以继承基本模型(参见 https://docs.djangoproject.com/es/1.9/topics/db/models/#abstract-base-classes)。然后,您可以为重构到基础(可以使用 A 或 B 的实例)的通用功能创建一个测试用例,然后为 A 和 B 的独特部分分离测试用例。