Django基础,Day6 - 单元测试tests

在django项目app目录下,有个tests.py,我们通常可以直接在这文件中写我们的单元测试代码。

test for a model

根据前面章节的操作步骤下来,在Question Model中有一个函数 was_published_recently(),判断文章发表时间在当前一天之内。代码如

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

仔细检查,可发现上述函数有个bug。如果发表时间在未来呢,按照上面的代码是会返回true的,显然不对。

编写测试用例 polls/tests.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from  django.test  import  TestCase
import  datetime
from  django.utils  import  timezone
from  .models  import  Question
 
 
class  QuestionMethodTests(TestCase):
 
     def  test_was_published_recently_with_future_question( self ):
         """
         was_published_recently() should return False for questions whose
         pub_date is in the future.
         """
         time  =  timezone.now()  +  datetime.timedelta(days = 30 )
         future_question  =  Question(pub_date = time)
         self .assertIs(future_question.was_published_recently(),  False )

运行测试用例

$ python manage.py test polls

运行结果如:

复制代码
Creating test database for alias 'default'...
F
======================================================================
FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionMethodTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "E:\workspace_python\mysite\polls\tests.py", line 16, 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.002s

FAILED (failures=1)
Destroying test database for alias 'default'...
复制代码

What happened is this:

  • python manage.py test polls looked for tests in the polls application
  • it found a subclass of the django.test.TestCase class
  • it created a special database for the purpose of testing
  • it looked for test methods - ones whose names begin with test
  • in test_was_published_recently_with_future_question it created a Question instance whose pub_datefield is 30 days in the future
  • ... and using the assertIs() method, it discovered that its was_published_recently() returns True, though we wanted it to return False

修复该bug,代码如

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

重新运行测试代码,则用例通过。

复制代码
$ python manage.py test polls
Creating test database for alias 'default'...
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Destroying test database for alias 'default'...
复制代码

添加更多的测试用例,如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from  django.test  import  TestCase
import  datetime
from  django.utils  import  timezone
from  .models  import  Question
 
 
class  QuestionMethodTests(TestCase):
 
     def  test_was_published_recently_with_future_question( self ):
         """
         was_published_recently() should return False for questions whose
         pub_date is in the future.
         """
         time  =  timezone.now()  +  datetime.timedelta(days = 30 )
         future_question  =  Question(pub_date = time)
         self .assertIs(future_question.was_published_recently(),  False )
 
     def  test_was_published_recently_with_old_question( self ):
         """
         was_published_recently() should return False for questions whose
         pub_date is older than 1 day.
         """
         time  =  timezone.now()  -  datetime.timedelta(days = 30 )
         old_question  =  Question(pub_date = time)
         self .assertIs(old_question.was_published_recently(),  False )
 
     def  test_was_published_recently_with_recent_question( self ):
         """
         was_published_recently() should return True for questions whose
         pub_date is within the last day.
         """
         time  =  timezone.now()  -  datetime.timedelta(hours = 1 )
         recent_question  =  Question(pub_date = time)
         self .assertIs(recent_question.was_published_recently(),  True )
test for a view

以view.index 为例,显然现在的代码也有bug,显示了发布时间属于将来的文章,代码如

测试之前,先修复view.index 中应该不显示发布时间在将来的文章。测试代码代码如

polls/views.py:

polls/index.html:

 测试用例代码

Django provides a test Client to simulate a user interacting with the code at the view level

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from  django.test  import  TestCase
import  datetime
from  django.urls  import  reverse
from  django.utils  import  timezone
from  .models  import  Question
 
class  QuestionViewTests(TestCase):
     def  test_index_view_with_no_questions( self ):
         """
         If no questions exist, an appropriate message should be displayed.
         """
         response  =  self .client.get(reverse( 'polls:index' ))
         self .assertEqual(response.status_code,  200 )
         self .assertContains(response,  "No polls are available." )
         self .assertQuerysetEqual(response.context[ 'latest_question_list' ], [])
 
     def  test_index_view_with_a_past_question( self ):
         """
         Questions with a pub_date in the past should be displayed on the
         index page.
         """
         create_question(question_text = "Past question." , days = - 30 )
         response  =  self .client.get(reverse( 'polls:index' ))
         self .assertQuerysetEqual(
             response.context[ 'latest_question_list' ],
             [ '<Question: Past question.>' ]
         )
 
     def  test_index_view_with_a_future_question( self ):
         """
         Questions with a pub_date in the future should not be displayed on
         the index page.
         """
         create_question(question_text = "Future question." , days = 30 )
         response  =  self .client.get(reverse( 'polls:index' ))
         self .assertContains(response,  "No polls are available." )
         self .assertQuerysetEqual(response.context[ 'latest_question_list' ], [])
 
     def  test_index_view_with_future_question_and_past_question( self ):
         """
         Even if both past and future questions exist, only past questions
         should be displayed.
         """
         create_question(question_text = "Past question." , days = - 30 )
         create_question(question_text = "Future question." , days = 30 )
         response  =  self .client.get(reverse( 'polls:index' ))
         self .assertQuerysetEqual(
             response.context[ 'latest_question_list' ],
             [ '<Question: Past question.>' ]
         )
 
     def  test_index_view_with_two_past_questions( self ):
         """
         The questions index page may display multiple questions.
         """
         create_question(question_text = "Past question 1." , days = - 30 )
         create_question(question_text = "Past question 2." , days = - 5 )
         response  =  self .client.get(reverse( 'polls:index' ))
         self .assertQuerysetEqual(
             response.context[ 'latest_question_list' ],
             [ '<Question: Past question 2.>' '<Question: Past question 1.>' ]
         )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值