【问题标题】:django: test case for @property function of a Modeldjango:模型的@property 函数的测试用例
【发布时间】:2018-12-20 12:47:11
【问题描述】:

我有一个 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是否迟到或低于截止日期, Test 执行成功,但 并未真正测试 BookInstance 模型的 is_overdue()。 请指导我如何正确测试此功能!谢谢

【问题讨论】:

  • 首先:请修正你的代码缩进。因为它是 ATM,所以代码甚至是无效的(它不会编译)。
  • 好的,我是开发测试用例的新手,如果你能正确地指导我完成它@brunodesthuilliers
  • 我开发这个测试用例只是作为一个开始(要做的事情),这不是我所暗示的作为我将要推进的解决方案

标签: django django-models django-tests


【解决方案1】:

我认为你误解了测试用例在 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

【讨论】:

  • 哦,好的,现在我明白了
【解决方案2】:

这是一个合适的测试用例。请注意,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")

【讨论】:

    【解决方案3】:

    您可以简单地创建一个实例并从该实例获取属性。

    instance = BookInstance(due_back=datetime.today())
    
    # Then property can be accessed like this
    instance.is_overdue 
    

    【讨论】:

      猜你喜欢
      • 2017-09-06
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      相关资源
      最近更新 更多