Django 项目测试
[TOC]
1. 概述
测试在项目开发中有着举足轻重的作用,可以提供有效便捷的代码检查.测试可以分为不同的level,有些测试关注于小的细节,比如一个model是否返回所需要的值,有的关注于项目的整体操作,比如输入用户的操作序列是否得到期待的结果.
Django提供了自动测试系统,可以通过编写测试代码提高代码可用性.有的程序猿遵守test-driven devlopment
即测试驱动开发,测试代码先于项目代码实现,,测试驱动开发简单地把所有问题放在了测试用例中,如果在开发过程中的代码实现不能满足测试的需求,系统就会报错,从而简化了寻找系统bug的过程,使用测试的好处如下
save your time
对于较为复杂的应用程序,在不同的组分之间可能有较多的耦合关联,一个元素的改变可能造成应用程序难以预料的行为,检查这些依赖需要大量的时间,但是通过自动测试,可以在瞬间玩策划那个对于各种依赖的检查
Tests don't identify problems, they prevent them
测试并不是开发中的负面因素,很多认为无法意识到的错误可以被自动检测
Tests make your code more attractive
Tests help teams work together
2. 基本测试技巧
在Django项目中的每一个app下都有一个tests.py文件,该app中所有的行为测试都可以放在该文件中,通过对视图或者行为建立测试函数,运行python3 manage.py test app
即可得到测试结果
import datetime
from django.test import TestCase
from django.utils import timezone
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)
def test_was_published_recently_with_old_question(self):
"""
was_published_recently() returns False for questions whose pub_date
is older than 1 day.
"""
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):
"""
was_published_recently() returns True for questions whose pub_date
is within the last day.
"""
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)
对于未来问题的测试,要求该函数返回False,可是在最初的实现中并没有得到预期的结果,所以需要进行更改
对于涉及时间点的测试,一般要包含,过去,现在,未来,以及临界点的测试
Shell test
django提供了一个用户模拟端,进行用户行为的模拟,可以在tests.py或者shell中使用
>>> from django.test.utils import setup_test_environment
>>> setup_test_environment()
>>> from django.test import Client
>>> # create an instance of the client for our use
>>> client = Client()
>>> # get a response from '/'
>>> response = client.get('/')
Not Found: /
>>> # we should expect a 404 from that address; if you instead see an
>>> # "Invalid HTTP_HOST header" error and a 400 response, you probably
>>> # omitted the setup_test_environment() call described earlier.
>>> response.status_code
404
>>> # on the other hand we should expect to find something at '/polls/'
>>> # we'll use 'reverse()' rather than a hardcoded URL
>>> from django.urls import reverse
>>> response = client.get(reverse('polls:index'))
>>> response.status_code
200
>>> response.content
b'\n <ul>\n \n <li><a href="/polls/1/">What's up?</a></li>\n \n </ul>\n\n'
>>> response.context['latest_question_list']
<QuerySet [<Question: What's up?>]>
setup_test_environment() 安装了一个template renderer ,提供了访问response.context 的方法,该方法并不会创建一个test database
3. views test
依照之前的实现,所有在未来发布的问题也都会在list展示,所以对views.py进行更改
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]
pub_date__lte表示小于等于该筛选值
4. 测试越多越好
可能测试代码会多余项目代码,但是是值得的,虽然会有多余的测试,但是不需要减少,测试代码只需要添加,因为进行自动测试的时间很短,效果却十分显著,一些基本的守则:
对于每一个model view设置一个单独的测试类
每一个想要测试的情况设置一个单独的测试方法\
方法名描述测试行为
Last updated
Was this helpful?