django:模型的@属性 函数的测试用例
django: test case for @property function of a Model
我有一个 Django 库应用程序,它具有以下 BookInstance 模型:
class BookInstance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4,help_text='Unique ID for this particular book across whole library')
book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
due_back = models.DateField(null=True, blank=True)
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
STATUS_MAINTENANCE = 'm'
STATUS_ON_LOAN = 'o'
STATUS_AVAILABLE = 'a'
STATUS_RESERVED = 'r'
LOAN_STATUS = (
(STATUS_MAINTENANCE, 'Maintenance'),
(STATUS_ON_LOAN, 'On loan'),
(STATUS_AVAILABLE, 'Available'),
(STATUS_RESERVED, 'Reserved'),
)
status = models.CharField(
max_length=1,
choices=LOAN_STATUS,
blank=True,
default=STATUS_MAINTENANCE,
help_text='Book availability',
)
class Meta:
ordering = ['due_back']
permissions = (("can_mark_returned", "Set book as returned"), ("can_create_book", "Create new book"), ("can_update_book", "Update book details"), ("can_delete_book", "Delete book"),)
# how to develop test case for this function
@property
def is_overdue(self):
if self.due_back and date.today() > self.due_back:
return True
return False
在我的 tests.py 文件中,我有 test_object_name_is_name 函数来测试它,但是我的覆盖率报告显示该函数没有经过测试。
class BookInstanceModelTest(TestCase):
"""
Test case for Book Instance
"""
@classmethod
def setUpTestData(cls):
# Set up non-modified objects used by all test methods
test_user1 = User.objects.create_user(username='testuser1', password='1X<ISRUkw+tuK',
email='testuser1@test.com')
test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&3iD',
email='testuser2@test.com')
test_author = Author.objects.create(first_name='William', last_name='Shakespeare')
test_book = Book.objects.create(title='Hamlet', author=test_author, summary='Published in 1990',
isbn='123456789123')
genre_objects_for_book = Genre.objects.all()
test_book.genre.set(genre_objects_for_book)
return_date1 = datetime.date.today()
BookInstance.objects.create(book=test_book, borrower=test_user1, due_back=return_date1,
status='o')
return_date2 = datetime.date.today() + datetime.timedelta(days=5)
BookInstance.objects.create(book=test_book, borrower=test_user2, due_back=return_date2,
status='o')
return_date3 = datetime.date.today() - datetime.timedelta(days=5)
BookInstance.objects.create(book=test_book, borrower=test_user2, due_back=return_date3,
status='o')
# test case I developed
def test_book_is_overdue(self):
last_date = datetime.date.today()
for book in BookInstance.objects.all():
if book.due_back == last_date:
self.assertTrue(True)
elif book.due_back > last_date:
self.assertTrue(True)
elif book.due_back < last_date:
self.assertFalse(False)
我检查了 due_back 是否迟到或低于截止日期,
测试成功执行,但 并未实际测试 BookInstance 模型的 is_overdue()。
请指导我如何正确测试此功能!谢谢
我认为您误解了测试用例在 Django 中的工作方式;您应该在测试方法前加上 test_
前缀,然后是您想要的任何名称,但它对功能并不重要,也不会调用函数。
要测试您的 属性,您应该在测试中调用它:
def test_book_is_overdue(self):
last_date = datetime.date.today()
for book in BookInstance.objects.all():
value = book.is_overdue
# test whatever you want
这是一个合适的测试用例。请注意,1/ 我为每个条件创建一个测试方法(我单独测试每个条件)和 2/ 我创建要在测试方法本身中测试的书(使测试更加明显和可读)。我只将 setUp()
用于测试所需的固定装置,但不是测试本身的一部分。此外,我在 self.assertXXX
调用中添加了更多明确的错误消息(因为将 "False is not True" 作为失败测试的报告并没有真正帮助)。
class BookInstanceModelTest(TestCase):
def setUp(self):
self.test_user1 = User.objects.create_user(
username='testuser1',
password='1X<ISRUkw+tuK',
email='testuser1@test.com'
)
self.test_author = Author.objects.create(
first_name='William',
last_name='Shakespeare'
)
self.test_book = Book.objects.create(
title='Hamlet',
author=self.test_author,
summary='Published in 1990',
isbn='123456789123'
)
genre_objects_for_book = Genre.objects.all()
self.test_book.genre.set(genre_objects_for_book)
def test_book_is_not_overdue_if_due_back_date_is_today(self)
due_date = datetime.date.today()
book = BookInstance.objects.create(
book=self.test_book,
borrower=self.test_user1,
due_back=due_date,
status='o'
)
self.assertFalse(book.is_overdue, "book should not be overdue")
def test_book_is_not_overdue_if_due_back_date_is_later_than_today(self):
due_date = datetime.date.today() + datetime.timedelta(days=5)
book = BookInstance.objects.create(
book=self.test_book,
borrower=self.test_user1,
due_back=due_date,
status='o'
)
self.assertFalse(book.is_overdue, "book should not be overdue")
def test_book_is_not_overdue_if_due_back_date_is_none(self):
due_date = None
book = BookInstance.objects.create(
book=self.test_book,
borrower=self.test_user1,
due_back=due_date,
status='o'
)
self.assertFalse(book.is_overdue, "book should not be overdue")
def test_book_is_overdue_if_due_back_date_is_past(self):
due_date = datetime.date.today() - datetime.timedelta(days=5)
book = BookInstance.objects.create(
book=self.test_book,
borrower=self.test_user1,
due_back=due_date,
status='o'
)
self.assertTrue(book.is_overdue, "book should be overdue")
您可以简单地创建一个实例并从该实例中获取 属性。
instance = BookInstance(due_back=datetime.today())
# Then property can be accessed like this
instance.is_overdue
我有一个 Django 库应用程序,它具有以下 BookInstance 模型:
class BookInstance(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4,help_text='Unique ID for this particular book across whole library')
book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
due_back = models.DateField(null=True, blank=True)
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
STATUS_MAINTENANCE = 'm'
STATUS_ON_LOAN = 'o'
STATUS_AVAILABLE = 'a'
STATUS_RESERVED = 'r'
LOAN_STATUS = (
(STATUS_MAINTENANCE, 'Maintenance'),
(STATUS_ON_LOAN, 'On loan'),
(STATUS_AVAILABLE, 'Available'),
(STATUS_RESERVED, 'Reserved'),
)
status = models.CharField(
max_length=1,
choices=LOAN_STATUS,
blank=True,
default=STATUS_MAINTENANCE,
help_text='Book availability',
)
class Meta:
ordering = ['due_back']
permissions = (("can_mark_returned", "Set book as returned"), ("can_create_book", "Create new book"), ("can_update_book", "Update book details"), ("can_delete_book", "Delete book"),)
# how to develop test case for this function
@property
def is_overdue(self):
if self.due_back and date.today() > self.due_back:
return True
return False
在我的 tests.py 文件中,我有 test_object_name_is_name 函数来测试它,但是我的覆盖率报告显示该函数没有经过测试。
class BookInstanceModelTest(TestCase):
"""
Test case for Book Instance
"""
@classmethod
def setUpTestData(cls):
# Set up non-modified objects used by all test methods
test_user1 = User.objects.create_user(username='testuser1', password='1X<ISRUkw+tuK',
email='testuser1@test.com')
test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&3iD',
email='testuser2@test.com')
test_author = Author.objects.create(first_name='William', last_name='Shakespeare')
test_book = Book.objects.create(title='Hamlet', author=test_author, summary='Published in 1990',
isbn='123456789123')
genre_objects_for_book = Genre.objects.all()
test_book.genre.set(genre_objects_for_book)
return_date1 = datetime.date.today()
BookInstance.objects.create(book=test_book, borrower=test_user1, due_back=return_date1,
status='o')
return_date2 = datetime.date.today() + datetime.timedelta(days=5)
BookInstance.objects.create(book=test_book, borrower=test_user2, due_back=return_date2,
status='o')
return_date3 = datetime.date.today() - datetime.timedelta(days=5)
BookInstance.objects.create(book=test_book, borrower=test_user2, due_back=return_date3,
status='o')
# test case I developed
def test_book_is_overdue(self):
last_date = datetime.date.today()
for book in BookInstance.objects.all():
if book.due_back == last_date:
self.assertTrue(True)
elif book.due_back > last_date:
self.assertTrue(True)
elif book.due_back < last_date:
self.assertFalse(False)
我检查了 due_back 是否迟到或低于截止日期, 测试成功执行,但 并未实际测试 BookInstance 模型的 is_overdue()。 请指导我如何正确测试此功能!谢谢
我认为您误解了测试用例在 Django 中的工作方式;您应该在测试方法前加上 test_
前缀,然后是您想要的任何名称,但它对功能并不重要,也不会调用函数。
要测试您的 属性,您应该在测试中调用它:
def test_book_is_overdue(self):
last_date = datetime.date.today()
for book in BookInstance.objects.all():
value = book.is_overdue
# test whatever you want
这是一个合适的测试用例。请注意,1/ 我为每个条件创建一个测试方法(我单独测试每个条件)和 2/ 我创建要在测试方法本身中测试的书(使测试更加明显和可读)。我只将 setUp()
用于测试所需的固定装置,但不是测试本身的一部分。此外,我在 self.assertXXX
调用中添加了更多明确的错误消息(因为将 "False is not True" 作为失败测试的报告并没有真正帮助)。
class BookInstanceModelTest(TestCase):
def setUp(self):
self.test_user1 = User.objects.create_user(
username='testuser1',
password='1X<ISRUkw+tuK',
email='testuser1@test.com'
)
self.test_author = Author.objects.create(
first_name='William',
last_name='Shakespeare'
)
self.test_book = Book.objects.create(
title='Hamlet',
author=self.test_author,
summary='Published in 1990',
isbn='123456789123'
)
genre_objects_for_book = Genre.objects.all()
self.test_book.genre.set(genre_objects_for_book)
def test_book_is_not_overdue_if_due_back_date_is_today(self)
due_date = datetime.date.today()
book = BookInstance.objects.create(
book=self.test_book,
borrower=self.test_user1,
due_back=due_date,
status='o'
)
self.assertFalse(book.is_overdue, "book should not be overdue")
def test_book_is_not_overdue_if_due_back_date_is_later_than_today(self):
due_date = datetime.date.today() + datetime.timedelta(days=5)
book = BookInstance.objects.create(
book=self.test_book,
borrower=self.test_user1,
due_back=due_date,
status='o'
)
self.assertFalse(book.is_overdue, "book should not be overdue")
def test_book_is_not_overdue_if_due_back_date_is_none(self):
due_date = None
book = BookInstance.objects.create(
book=self.test_book,
borrower=self.test_user1,
due_back=due_date,
status='o'
)
self.assertFalse(book.is_overdue, "book should not be overdue")
def test_book_is_overdue_if_due_back_date_is_past(self):
due_date = datetime.date.today() - datetime.timedelta(days=5)
book = BookInstance.objects.create(
book=self.test_book,
borrower=self.test_user1,
due_back=due_date,
status='o'
)
self.assertTrue(book.is_overdue, "book should be overdue")
您可以简单地创建一个实例并从该实例中获取 属性。
instance = BookInstance(due_back=datetime.today())
# Then property can be accessed like this
instance.is_overdue