Django-part5

2020-06-29  本文已影响0人  一技破万法

自动化测试

什么是自动化测试

测试软件编写

Django是一个全面、完善、严谨的Web框架,当然不会缺少测试功能。

'1.遇见BUG'
很巧,在我们的投票应用中有一个小bug需要修改:在Question.was_published_recently()方法的返回值中,当Qeustion在最近的一天发布的时候返回True(这是正确的),然而当Question在未来的日期内发布的时候也返回True(这是错误的)。

我们可以在admin后台创建一个发布日期在未来的Question,然后在shell中验证这个bug:

$ python manage.py shell
>>> import datetime
>>> from django.utils import timezone
>>> from polls.models import Question
>>> # 创建一个发布日期在30天后的问卷
>>> future_question = Question(pub_date=timezone.now() + datetime.timedelta(days=30))
>>> # 测试一下返回值
>>> future_question.was_published_recently()
True

问题的核心在于我们允许创建在未来时间才发布的问卷,由于“未来”不等于“最近”,因此这显然是个bug。

创建测试来暴露BUG

刚才我们是在shell中测试了这个bug,那如何通过自动化测试来发现这个bug呢?
通常,我们会把测试代码放在应用的tests.py文件中,测试系统将自动地从任何名字以test开头的文件中查找测试程序。每个app在创建的时候,都会自动创建一个tests.py文件,就像views.py等文件一样。
将下面的代码输入投票应用的polls/tests.py文件中:

import datetime
from django.utils import timezone
from django.test import TestCase
from .models import Question

class QuestionMethodTests(TestCase):
    def test_was_published_recently_with_future_question(self):
        """
        在将来发布的问卷应该返回False
        """
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(pub_date=time)
        self.assertIs(future_question.was_published_recently(), False)

我们在这里创建了一个django.test.TestCase的子类,它具有一个方法,该方法创建一个pub_date在未来的Question实例。最后我们检查was_published_recently()的输出,它应该是 False。

运行测试程序

在终端中,运行下面的命令,

$ python manage.py test polls

你将看到结果如下:

Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionMethodTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Volumes/Kyt/team/djando/polls/tests.py", line 15, in test_was_published_recently_with_future_question
    self.assertIs(future_question.was_published_recently(),False)
AssertionError: True is not False

----------------------------------------------------------------------
Ran 1 test in 0.003s

FAILED (failures=1)
Destroying test database for alias 'default'...

这其中都发生了些什么?:

修复BUG

我们已经知道了问题所在,现在可以去修复bug了。修改源代码,具体如下:

# polls/models.py

def was_published_recently(self):
    now = timezone.now()
    return now - datetime.timedelta(days=1) <= self.pub_date <= now

更加全面的测试

事实上,前面的测试用例还不够完整,为了使was_published_recently()方法更加可靠,我们在上面的测试类中再额外添加两个其它的方法,来更加全面地进行测试。

# polls/tests.py

def test_was_published_recently_with_old_question(self):
    """
    只要是超过1天的问卷,返回False
    """
    time = timezone.now() - datetime.timedelta(days=1, seconds=1)
    old_question = Question(pub_date=time)
    self.assertIs(old_question.was_published_recently(), False)

def test_was_published_recently_with_recent_question(self):
    """
    最近一天内的问卷,返回True
    """
    time = timezone.now() - datetime.timedelta(hours=23, minutes=59, seconds=59)
    recent_question = Question(pub_date=time)
    self.assertIs(recent_question.was_published_recently(), True)
一技破万法
上一篇下一篇

猜你喜欢

热点阅读