django测试(一)
引用于[url=http://yimogod.javaeye.com/blog/153134]http://yimogod.javaeye.com/blog/153134[/url]对于当今Web developer来说,自动化测试是一项非常有用的”除虫”工具。你可以使用测试集——test suite——去避免或者解决一系列的问题:
当你在写新代码的时候,测试可以验证你的代码是否按预期执行
当你重构或则修改旧代码时,你可以使用测试来确保你的修改不会对程序造成不良影响
测试Web 程序是一项复杂的工作。因为一个Web程序由多种逻辑层组成——从Http层的request 执行,到表单的确定和处理,到模板的渲染。利用Django测试框架以及齐全的配套工具,
你可以模request,插入测试数据,检查程序输出和一般情况下的测试。
最重要的是,Django测试框架非常简单!
Django中,测试由两种方式:doctests 和unit tests。
doctests:
doctests使用的是python中标准的doctest测试模块。它是由系统在你的docstring(注释)中查找测试代码。
Django 的test runner在你的models.py文件中查找并执行你的doctests。如果找到tests.py文件,它同样会去里面查找doctests。
你可以将doctest语句放入你工程中的任何models.py文件中。但一般情况下,会将app的doctests放在module docstring中,而model的doctests会放在各自的model中
举例:
from django.db import model
class Animal(models.Model):
"""
An animal that knows how to make noise
# Create some animals
>>> lion = Animal.objects.create(name="lion", sound="roar")
>>> cat = Animal.objects.create(name="cat", sound="meow")
# Make 'em speak
>>> lion.speak()
'The lion says "roar"'
>>> cat.speak()
'The cat says "meow"'
"""
name = models.CharField(maxlength=20)
sound = models.CharField(maxlength=20)
def speak(self):
return 'The %s says "%s"' % (self.name, self.sound)
当你运行测试的时候,test utility会找到这个docstring。这里需要注意一下,上面的docstring有
部分类似于python的交互环境。好了,运行它吧。
unittests:
Django的unit tests使用的标准模块库是unittest。和doctests一样,Django的test runner 在
models.py文件或者在app目录下存在的tests.py文件中查找定义了的unit test cases。
一个与上例doctests等价的unittest test case如下:
import unittest
from myapp.models import Animal
class AnimalTestCase(unittest.TestCase):
def setUp(self):
self.lion = Animal.objects.create(name="lion", sound="roar")
self.cat = Animal.objects.create(name="cat", sound="meow")
def testSpeaking(self):
self.assertEquals(self.lion.speak(), 'The lion says "roar"')
self.assertEquals(self.cat.speak(), 'The cat says "meow"')
当你运行tests的时候,test utility会找到models.py 和tests.py文件中所有的test case,在这些
test case外自动构造一个test suite,并运行它。
我应该用哪种?
选择哪一个测试框架经常是有争议的,所以Django同时支持python的两种标注测试框架。选择哪一
个取决于程序员个人的爱好。Django对于两种测试框架给与相同的支持。因为每一种测试系统都有自身
的优点,所以最好的方法是将两者结合使用,使用对你测试最合适的测试系统。
对于一个程序测试新手,这种选择可能会令人迷惑,所以这里给出了两种测试系统的一些诧异,以
帮助你选择一个适合你的。
如果你已经使用Python一段时间,doctest可能你会觉得doctest更Python一些。它让写测试尽
量简单,(so there’s no overhead of writing classes or methods不知道咋翻译;()你只是简单
的把测试代码放入了docstrings中。这样有一个附加的好处就是同时给modules提供了一份documentation
——好的doctests可以兼顾test和documentation,一石二鸟。
如果你刚开始学习测试,那么doctests会让你快速入门。
Unittest会让从java转过来的程序员觉得熟悉。因为unittest就是从Junit处获得灵感的。如果你
有使用过类似于Junit测试框架的经验,那unittest会让你更习惯些。
Unittest是根据class和method组织的,如果你在为一些类似的代码写一系列测试,那么你可以使
用它的子集去抽象出它的共同任务。这样可以使你的代码小巧而整洁。它也提供直接的安装和卸载程序,
可以使你在一个更高的层面上控制你的test case 运行的环境。
重申,你可以并行的使用两种测试系统,甚至在同一个app中。大部分的项目都会用到这两种测试
系统。两个测试系统都能找到更适合自己的位置。
运行tests
你可以使用下列语句运行你的测试
$ ./manage.py test
默认情况下,它会运行你项目里写在INSTALLED_APPS里所有app的测试. 如果你只想要测试其中某一个app,你比如说animals(假设你的INSTALLED_APPS里有两个app--myproject.polls和myproject.animals) ,你可以运行以下
命令来达到目的
# ./manage.py test animals
注意,我们使用了animals,而不是myproject.animals
现在你可以(svn版本)针对更细力度的test class 或者 test method进行测试了.
比如你的animals app 的测试单元里有AnimalTestCase测试类,这个类拥有testFluffyAnimals这个测试方法.那么,你可以通过
$ ./manage.py test animals.AnimalTestCase
来只运行AnimalTestCase这个测试类,通过
$ ./manage.py test animals.AnimalTestCase.testFluffyAnimals
来运行testFluffyAnimals这个测试方法.
测试数据库
测试运行需要的数据库并不需要你真实的数据库.一个单独的测试数据库会被创建.
不管你的测试是否通过,当你所有的测试都执行过后,这个测试数据库就会被销毁.
默认情况下,测试数据库的名字是test_DATABASE_NAME,DATABASE_NAME是你在settings.py里配置的数据库名.如果你需要给测试数据库一个其他的名字,在settings.py中指定TEST_DATABASE_NAME的值.
除了使用一个单独的数据库外,测试工具会使用相同的数据库配置--DATABASE_ENGINE, DATABASE_USER, DATABASE_HOST等等.创建测试数据库的用户由DATABASE_USER(settings中)指定,所以你需要确认DATABASE_USER
有足够的权限去创建数据库.
理解test输出的内容
当你运行你的test后,你会看到一系列打印出来的信息.你可以在命令行中使用verbosity这个选项来控制输出信息的详细程度.
Creating test database...
Creating table myapp_animal
Creating table myapp_mineral
Loading 'initial_data' fixtures...
No fixtures found.
这段信息告诉你正在创建一个测试数据库.
当创建测试数据库后,Django就会运行你的test.如果你的所有测试都通过了,你会看到以下信息,
----------------------------------------------------------------------
Ran 22 tests in 0.221s
OK
如果有test没有通过,你会看到没有通过的test的细节:
======================================================================
FAIL: Doctest: ellington.core.throttle.models
----------------------------------------------------------------------
Traceback (most recent call last):
File "/dev/django/test/doctest.py", line 2153, in runTest
raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for myapp.models
File "/dev/myapp/models.py", line 0, in models
----------------------------------------------------------------------
File "/dev/myapp/models.py", line 14, in myapp.models
Failed example:
throttle.check("actor A", "action one", limit=2, hours=1)
Expected:
True
Got:
False
----------------------------------------------------------------------
Ran 2 tests in 0.048s
FAILED (failures=1)
一份完整的错误信息输出超出了本文档的范围,但这会让你更直观;)你可以去查看python的unittest库了解更多细节.
测试工具
Django提供了一系列小工具用来写测试.
Test Client
test client是一个python类,来模拟一个简单的“哑”浏览器,允许你来测试你的view函数.
你可以使用test client完成下列事情.
模拟"Get"和"Post"请求,观察响应结果--从HTTP(headers,status codes)到页面内容.
测试url执行了正确的view函数.
测试一个request被Django模板渲染.
Test Client无意于取代Twill,Selenium这些框架.Django有不同的专注点.
概略
使用test client,需要引入django.test.client.Client
>>> from django.test.client import Client
>>> c = Client()
>>> response = c.post('/login/', {'username': 'john', 'password': 'smith'})
>>> response.status_code
200
>>> response = c.get('/customer/details/')
>>> response.content
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...'
如例所示,你需要实例化Client.
接下页
[[i] 本帖最后由 zjxplq 于 2008-11-19 08:51 编辑 [/i]]
页:
[1]