Django基础,Day6 - 单元测试tests

it2024-10-03  20

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

test for a model

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

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

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

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

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 applicationit found a subclass of the django.test.TestCase classit created a special database for the purpose of testingit looked for test methods - ones whose names begin with testin 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,代码如

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'...

添加更多的测试用例,如

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

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.>'] )

 


***微信扫一扫,关注“python测试开发圈”,了解更多测试教程!***

转载于:https://www.cnblogs.com/guanfuchang/p/6258035.html

相关资源:数据结构—成绩单生成器
最新回复(0)