(5) django官方教程---自动化测试

基本知识

测试是一种简单的日常生活,用于检测代码操作。测试操作可以处于水平。有些可能只是测试细小部分如某个模型方法,然而其他的检测软件的整理操作,这和之前的在教程2中使用的测试没什么区别,使用shell测量方法,运行应用程序以及输入数据检测行为。自动化测试的区别是测试工作是由系统为你做的。一旦你编写好了测试集,当你对app做出调整时你就可以检测代码是否符合初期目标。

测试有以下好处:
节省时间,鉴别问题并阻止问题,让代码更有吸引力,促进团队合作

基本测试策略
有些开发者遵循“测试驱动开发”的原理,描述一个问题,然后写代码解决它。
有些新人可能会先写一些代码然后发现应该写一些测试。或许早一些写测试更好,但任何时候开始都不会迟。
有时候很难弄清从哪里开始写测试,那么下次你做出改变时就应该编写测试代码,或者是你添加了一个新特性,或者是修复了一个bug。

测试实践

按照如下方式测试was_published_recently,创建一个问题question , 其创建时间是未来

>>> import datetime
>>> from django.utils import timezone
>>> from polls.models import Question
>>> # create a Question instance with pub_date 30 days in the future
>>> future_question = Question(pub_date=timezone.now() + datetime.timedelta(days=30))
>>> # was it published recently?
>>> future_question.was_published_recently()
True

以上是基于shell的测试,现在我们编写自动化测试。我们可以在Polls/tests.py中编写如下测试

import datetime

from django.utils import timezone
from django.test import TestCase

from .models import Question


class QuestionModelTests(TestCase):

    def test_was_published_recently_with_future_question(self):
        """
        was_published_recently() returns 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

过程如下:
1.寻找poll应用程序中的测试
2.发现django.test.TestCase的子类
3.为了测试需要创建特殊的数据库
4.寻找测试方法,名字以test开头
5.执行测试方法,创建了Question实例。使用assertIs方法,函数返回的是True,而我们想要的是False。

修改模型,修复bug

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

datetime.timedelta表示一个时间区间
class datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
所有参数都是可选的,默认为0

当然我们可以为此方法写更综合的测试。这里我们先写了一个测试代码,然后去修复这个bug,这就是一个简单的测试驱动开发实例。

测试视图

django测试客户端:在视图级别模拟用户与代码的交互
如果使用shell测试,我们需要:
安装模板渲染器,允许我们测试响应的更多属性。它不会创建数据库,因此我们之后的测试是基于已有的数据库

>>> from django.test.utils import setup_test_environment
>>> setup_test_environment()

导入测试客户端

>>> from django.test import Client
>>> client = Client()

接着

response = client.get(reverse('polls:index'))
response.status_code
response.content
response.context['latest_question_list']

改善视图
修改IndexView,过滤未来的Question

from django.utils import timezone
def get_queryset(self):
    """
    Return the last five published questions (not including those set to be
    published in the future).
    """
    return Question.objects.filter(
        pub_date__lte=timezone.now()
    ).order_by('-pub_date')[:5]

为新view创建自动化测试

def create_question(question_text, days):
    """
    Create a question with the given `question_text` and published the
    given number of `days` offset to now (negative for questions published
    in the past, positive for questions that have yet to be published).
    """
    time = timezone.now() + datetime.timedelta(days=days)
    return Question.objects.create(question_text=question_text, pub_date=time)


class QuestionIndexViewTests(TestCase):
    def test_no_questions(self):
        """
        If no questions exist, an appropriate message is 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_past_question(self):
        """
        Questions with a pub_date in the past are 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_future_question(self):
        """
        Questions with a pub_date in the future aren't 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_future_question_and_past_question(self):
        """
        Even if both past and future questions exist, only past questions
        are 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_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.>']
        )

与之前assertIs类似的方法有
self.assertEqual(response.status_code, 200)
self.assertContains(response, “No polls are available.”)
self.assertQuerysetEqual(response.context[‘latest_question_list’], [])。

多考虑可能出现的情况,并为此编写测试代码。测试越多越好,为了测试便于管理,我们需要遵循如下原则:
1.为每个模型或视图建立单独的测试类
2.为每种情况建立单独的测试方法
3.测试方法基于方法命名

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值