一切花哨的UI,其目的只不过是将内容更好的展示出来。记django的官方文档。
django文档中我比较中意的包括model,template,view,forms,还有Testing。
按照我的习惯,测试先行。先看Testing。
我自己已经习惯了单元测试,就捡我在意的看。
from django.utils import unittest实际上用到的是一个叫做unittest2的模块。
单元测试在涉及到数据库时,会新建一个新的数据库(新的,当然里面就没有数据了),在测试结束后又会销毁这个数据库。
之后有什么master/slave google了一下,觉得做靠谱的说法是:http://wushaobo.info/?p=52,其中最重要的代码是:
'TEST_MIRROR': 'default'这个设置只是为了在testing的过程中声明:哪一个数据库应该被mirror(不知道是怎样一个动作)
在这里我小白了:django可以配置这么多数据库!!还能在测试的过程中指定每个测试专用数据库的创建顺序。
TEST_CHARSET TEST_DEPENDENCIES TEST_MIRROR TEST_NAME
分别用于设置testing时的字符集,配置数据库的创建顺序,MIRROR和指定测试数据库的名称
'TEST_DEPENDENCIES': ['diamonds','hearts']
接下来django提供的测试工具
from django.test.client import Client你可以用这个工具来:
- 模拟GET和POST请求,观察response。
- 测试一个给定的URL是否访问到正确的view
- 测试一个给定的request是否是被给定的 template 和 模版上下文所处理的。
content_type:可以是: text/xml 等。这时data会被当作xml处理(我大脑有点短路了,HOW??)
{'choices': ('a', 'b', 'd')}
f = open('wishlist.doc') >>> c.post('/customers/wishes/', {'name': 'fred', 'attachment': f})post和get方法都会返回一个Response对象
对象有:
- client
- content
- context
- request
- status_code
- templates
Client.cookies
Client.session
RequestFactory:有着和client一样的API,但最大的不同是:
self.factory = RequestFactory()
request = self.factory.get('/customer/details')
response = my_view(request)这样,你直接调用了my_view函数,而不是通过模拟浏览器。
unittest类:
提供了:
自动加载fixtures;
把每个test当成一个事物,可以回滚
有一个内置的 client 实例
django专用的断言:比如网页重定向和表单错误
下面一一详解:
自动加载fixtures:(fixtures是django知道如何导入到数据库的数据集,推荐用manage.py dumpdata命令自动生成,详情https://docs.djangoproject.com/en/1.4/ref/django-admin/#django-admin-dumpdata)
fixtures = ['mammals.json', 'birds']#两个都是文件名
urls = 'myapp.test_urls'
可以配置测试时的setting,就是setting.py那个文件。方法如下:
with self.settings(LOGIN_URL='/other/login/'):或者
@override_settings(LOGIN_URL='/other/login/') def test_login(self):
@override_settings(LOGIN_URL='/other/login/') class LoginTestCase(TestCase):
提供了好多django专有的assert(看了文档根本不知道怎么用)(TestCase类中的方法)
TestCase.assertContains(response, text, count=None, status_code=200, msg_prefix='', html=False)
1.response的状态码
2.text在content中出现过(如果给定了count,则text中的文本恰好出现count次)
3.将html设置为true,则text将被当作html对待。
TestCase.assertNotContains(response, text, status_code=200, msg_prefix='', html=False)
TestCase.assertFormError(response, form, field, errors, msg_prefix='')
看文档看不懂,找了一个实例:
def test_registration_view_failure(self):
"""
A ``POST`` to the ``register`` view with invalid data does not
create a user, and displays appropriate error messages.
"""
response = self.client.post(reverse('registration_register'),
data={'username': 'bob',
'email': 'bobe@example.com',
'password1': 'foo',
'password2': 'bar'})
self.assertEqual(response.status_code, 200)
self.failIf(response.context['form'].is_valid())
self.assertFormError(response, 'form', field=None,
errors=u"The two password fields didn't match.")
self.assertEqual(len(mail.outbox), 0)
Asserts that a field on a form raises the provided list of errors when rendered on the form.
断言form上的某个字段是否抛出了和errors变量一样的错误提示。
form:一个Form实例在template的上下文中所配置的name
field:我觉得设置为None就好了。
TestCase.assertTemplateUsed(response, template_name, msg_prefix='')
self.assertTemplateUsed(response, 'registration/test_template_name.html')
TestCase. assertTemplateNotUsed ( response , template_name , msg_prefix='' )
TestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200,msg_prefix='')