标签:
Test——很重要但是没有被重视起来的一个环节,至少是我自己,其实自己之前在做java web的时候就去尝试过怎么做REST接口的测试,一直没有找到一种合适方式,而且因为时间紧没有进一步深究,但是造成的后果每次做了修改之后都测试不充分,引起新的问题,所以这次对于python正好看看Django的单元测试。
用的是单独的数据库,数据库是干净的(暂未有数据库,test所有操作都是从零开始),不会对正式的数据库造成影响
到现在我们主要的业务逻辑代码在model和view里面,所以我们的测试也主要是针对model和view。在Django中我们的测试代码写在tests.py里面,这里我们先在models.py的Question类里面添加一个was_published_recently方法:
def was_published_recently(self): now = timezone.now() return self.publ_date >= now - datetime.timedelta(days=1)
接下来针对这个方法写单元测试
class QuestionMethodTest(TestCase): def test_was_pblished_recently_with_future_question(self): time = timezone.now() + datetime.timedelta(days=30) future_question = Question(publ_date=time) self.assertEqual(future_question.was_published_recently(), False) def test_was_pblished_recently_with_old_question(self): time = timezone.now() - datetime.timedelta(days=30) future_question = Question(publ_date=time) self.assertEqual(future_question.was_published_recently(), False) def test_was_pblished_recently_with_recently_question(self): time = timezone.now() - datetime.timedelta(hours=1) future_question = Question(publ_date=time) self.assertEqual(future_question.was_published_recently(), True)
这里先写了三个测试用例,分别测试
我们再看看Django为我们的单元测试提供了怎样的环境。
我们在mysite目录里面运行测试
python manage.py test polls
可以看到输出
Creating test database for alias ‘default‘... F.. ====================================================================== FAIL: test_was_pblished_recently_with_future_question (polls.tests.QuestionMethodTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/root/django/mysite/polls/tests.py", line 17, in test_was_pblished_recently_with_future_question self.assertEqual(future_question.was_published_recently(), False) AssertionError: True != False ---------------------------------------------------------------------- Ran 3 tests in 0.001s FAILED (failures=1) Destroying test database for alias ‘default‘...
可以看到总共三个测试,失败1个,查看失败信息发现返回的是true,和我们预期的不符,说明我们的was_published_recently函数的逻辑不正确,所有时间大于当前时间的应该不被查询出来,我们修正如下
def was_published_recently(self): now = timezone.now() return now >= self.publ_date >= now - datetime.timedelta(days=1)
再次运行就会发现三个均成功,结果是OK
Creating test database for alias ‘default‘... ... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK Destroying test database for alias ‘default‘...
view层会调用model层的代码实现业务逻辑,我们通过上面model的测试保证了model层的正确性,接下来可以借用django提供的环境测试我们的业务逻辑是否正确,编辑tests.py
from django.test import TestCase import datetime from django.utils import timezone from polls.models import Question from django.core.urlresolvers import reverse # Create your tests here. def create_question(question_text, days): time = timezone.now() + datetime.timedelta(days=days) return Question.objects.create(question_text=question_text, publ_date=time) class QuestionMethodTest(TestCase): def test_was_pblished_recently_with_future_question(self): time = timezone.now() + datetime.timedelta(days=30) future_question = Question(publ_date=time) self.assertEqual(future_question.was_published_recently(), False) def test_was_pblished_recently_with_old_question(self): time = timezone.now() - datetime.timedelta(days=30) future_question = Question(publ_date=time) self.assertEqual(future_question.was_published_recently(), False) def test_was_pblished_recently_with_recently_question(self): time = timezone.now() - datetime.timedelta(hours=1) future_question = Question(publ_date=time) self.assertEqual(future_question.was_published_recently(), True) class QuestionViewTest(TestCase): def test_index_view_with_no_questions(self): 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): create_question(‘Past question.‘, -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): create_question(‘Future question.‘, 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): create_question(‘Past question.‘, -30) create_question(‘Future question.‘, 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_question(self): create_question(‘Past question 1.‘, -30) create_question(‘Past question 2.‘, -5) response = self.client.get(reverse(‘polls:index‘)) self.assertQuerysetEqual(response.context[‘latest_question_list‘], [‘<Question: Past question 2.>‘, ‘<Question: Past question 1.>‘])
django为我们的view层测试提供了更多的帮助
完整代码
http://pan.baidu.com/s/1geJ7DYj
标签:
原文地址:http://www.cnblogs.com/sunshine-2015/p/5676873.html