hanyh 发表于 2013-1-15 02:47:54

doctest写测试非常爽:)

最近用django作点小项目,直接使用doctest,用起来真爽.
注意几点:
1,每个测试用例加注释,最好和对应的Ticket联系起来
2,当前Client工具足够好用
可以通过status_code,context,content来测试自己的view是否正确
3,可以直接查看models的数据,非常方便
4,比unittest的无用代码量少多了

示例代码如下:
有个tribe的app
中间建了一个tests的目录
tribe/tests$ more __init__.py# coding=UTF-8from django.contrib.auth.models import Userfrom tribe.forms import *from tribe.models import *from django.test import Clientimport osfrom django.contrib.auth.models import PermissionTEST_ROOT = os.path.dirname(__file__)import doctst__test__ = {    'Doctest': doctst}测试代码:# coding=UTF-8""">>> User.objects.all()[]>>> admin =User.objects.create_user('admin', 'admin@foo.com', 'eeeee')>>> admin.save()#Ticket #2 用户登录 account.custom_login>>> browser = Client()#invalid login>>> response = browser.post('/accounts/login/', {'username': 'orphan_user', 'password': 'xxx', 'remember':0})>>> response.status_code200#valid login with username>>> response = browser.post('/accounts/login/', {'username': 'admin', 'password': 'eeeee', 'remember':0})>>> response.status_code302#valid login with email>>> browser.logout()>>> response = browser.post('/accounts/login/', {'username': 'admin@foo.com', 'password': 'eeeee', 'remember':0})>>> response.status_code302#Ticket #5 小组类别列表 ,包括创建 create_category,list_category>>> Category.objects.all()[]>>> response = browser.post('/accounts/login/', {'username': 'admin@foo.com', 'password': 'eeeee', 'remember':0})#create root category>>> response = browser.post('/group/category/create/', {'name': 'music'})>>> Category.objects.all()[<Category: music>]>>> response = browser.post('/group/category/create/', {'name': 'book'})#create sub category>>> response = browser.post('/group/category/1/create/', {'name': 'classic'})>>> response = browser.post('/group/category/1/create/', {'name': 'artist'})#can't create>>> response = browser.post('/group/category/3/create/', {'name': 'third level categroy'})>>> response.status_code403>>> Category.objects.getList()[{'category': <Category: music>, 'count': 2, 'child_set': [<Category: classic>, <Category: artist>]}, {'category': <Category: book>, 'count': 0, 'child_set': []}]#小组首页 list_category>>> Category.objects.getList(0,1)[{'category': <Category: music>, 'count': 2, 'child_set': [<Category: classic>, <Category: artist>]}]>>> category = Category.objects.all()>>> category.nameu'music'>>> response = browser.get('/group/')>>> len(response.context['objects'])2#查看特定小组 view_category>>> response = browser.get('/group/category/1/')>>> response.context['objects'][<Category: classic>, <Category: artist>]>>> response = browser.get('/group/category/3/')>>> response.context['objects'][]#Ticket #6 创建小组create_tribe>>> response = browser.post('/accounts/login/', {'username': 'admin@foo.com', 'password': 'eeeee', 'remember':0})>>> img_path = os.path.join(TEST_ROOT,'default.jpg')>>> f = open(img_path)>>> response = browser.post('/group/category/3/create_tribe/', {'name': 'artist in china','desc':'group 1','icon':f})>>> f.close()>>> response.status_code302>>> response = browser.get('/group/category/3/')>>> response.context['objects'][<Tribe: artist in china>]#重构加入小组功能>>> Tribe.objects.all().get_managers()[<User: admin>]#不能在top category中创建小组>>> response = browser.post('/group/category/1/create_tribe/', {'name': 'artist in china','desc':'group 1'})>>> response.status_code403#Ticket #7 用户加入小组 join_tribe>>> tribe_user = User.objects.create_user('tribe_user','ee@eess.net','eeeee')>>> tribe_user.save()>>> browser.logout()>>> response = browser.post('/accounts/login/', {'username': 'tribe_user', 'password': 'eeeee', 'remember':0})>>> response.status_code302>>> response = browser.post('/group/1/join/')>>> response.content'{"msg": "msg", "result": "true"}'>>> tribe = Tribe.objects.all()#存在最初的创建者>>> tribe.members.count()2#unsubscribe_tribe>>> response = browser.post('/group/1/quit/')>>> tribe = Tribe.objects.all()>>> tribe.members.count()1>>> response = browser.post('/group/1/join/')#Ticket #8new_topic test>>> Topic.objects.all().count()0>>> response = browser.post('/group/1/new_topic/',{'title': 'test topic', 'content':'新内容'})>>> response.status_code302>>> Topic.objects.all().count()1#invalid new topic form test>>> response = browser.post('/group/1/new_topic/',{'title': '测试'})>>> response.status_code200>>> Topic.objects.all().count()1#create a tmp user to test invalid new_topic>>> t_user = User.objects.create_user('t_user','ee@e3.net','eeeee')>>> t_user.save()>>> response = browser.post('/accounts/login/', {'username': 't_user', 'password': 'eeeee', 'remember':0})>>> response = browser.post('/group/1/new_topic/',{'title': '测试', 'content':'新内容'})>>> response.status_code403#Test invalid reply>>> response = browser.post('/group/topic/1/reply/',{'content':'新内容'})>>> response.status_code403#Test valid replay>>> browser.logout()>>> response = browser.post('/accounts/login/', {'username': 'tribe_user', 'password': 'eeeee', 'remember':0})>>> response.status_code302>>> response = browser.post('/group/topic/1/reply/',{'content':'replay 1'})>>> Reply.objects.all().count()1>>> response = browser.post('/group/topic/1/reply/',{'content':'replay 2'})>>> response = browser.post('/group/topic/1/reply/',{'content':'replay 3'})>>> response = browser.post('/group/topic/1/reply/',{'content':'replay 4'})#小组话题列表Ticket #9 topic_list>>> response = browser.post('/group/1/new_topic/',{'title': 'topic1', 'content':'新内容'})>>> response = browser.post('/group/1/new_topic/',{'title': 'topic2', 'content':'新内容'})>>> response = browser.post('/group/1/new_topic/',{'title': 'topic3', 'content':'新内容'})>>> response = browser.get('/group/1/')>>> response.status_code200>>> response.context['topics'][<Topic: test topic>, <Topic: topic1>, <Topic: topic2>, <Topic: topic3>]#查看话题 view_topic>>> response = browser.get('/group/topic/1/')>>> response.context['topic']<Topic: test topic>>>> response.context['topic'].reply_set.all()[<Reply: replay 1>, <Reply: replay 2>, <Reply: replay 3>, <Reply: replay 4>]#Ticket #12查看话题 list_member>>> response = browser.get('/group/1/member/')>>> response.context['members'][<User: admin>, <User: tribe_user>]#Ticket #13自己加入 my_tribe#current user:tribe_user>>> response = browser.get('/group/mine/')>>> response.context['tribes'][<Tribe: artist in china>]>>> Tribe.objects.all()[<Tribe: artist in china>]#创建小组加入>>> response = browser.post('/group/category/3/create_tribe/', {'name': 'artist in china 2','desc':'group 2'})>>> response = browser.post('/group/category/3/create_tribe/', {'name': 'artist in china 3','desc':'group 3'})>>> response = browser.post('/group/category/3/create_tribe/', {'name': 'artist in china 4','desc':'group 4'})>>> response = browser.post('/group/1/join/')>>> response = browser.post('/group/2/join/')>>> response = browser.post('/group/3/join/')>>> browser.logout()>>> response = browser.post('/accounts/login/', {'username': 'tribe_user', 'password': 'eeeee', 'remember':0})>>> response = browser.get('/group/mine/')>>> response.context['tribes'][<Tribe: artist in china>, <Tribe: artist in china 2>, <Tribe: artist in china 3>, <Tribe: artist in china 4>]>>> response = browser.get('/group/1/quit/')>>> response = browser.get('/group/mine/')>>> response.context['tribes'][<Tribe: artist in china 2>, <Tribe: artist in china 3>, <Tribe: artist in china 4>]>>> response = browser.post('/group/1/join/')>>> response = browser.get('/group/1/latest_member/')>>> response.context['memberships'][<Membership: tribe_user is a member of 'artist in china'>, <Membership: admin is a member of 'artist in china'>]Ticket #14 我的发言>>> response = browser.get('/group/1/my_topic/')>>> response.context['topics'][<Topic: test topic>, <Topic: topic1>, <Topic: topic2>, <Topic: topic3>]Ticket #15>>> Tribe.objects.all()[<Tribe: artist in china>, <Tribe: artist in china 2>, <Tribe: artist in china 3>, <Tribe: artist in china 4>]>>> User.objects.all()[<User: admin>, <User: tribe_user>, <User: t_user>]>>> tribe = Tribe.objects.get(pk=1)>>> tribe.nameu'artist in china'>>> tribe.get_managers()[<User: admin>]>>> User.objects.get(pk=2).usernameu'tribe_user'>>> User.objects.get(pk=3).usernameu't_user'#添加管理员>>> response = browser.post('/group/1/grant/2/')>>> response.status_code403#添加管理员>>> browser.logout()>>> response = browser.post('/accounts/login/', {'username': 'admin', 'password': 'eeeee', 'remember':0})>>> response = browser.post('/group/1/grant/2/')>>> response.content'{"msg": "", "result": true}'>>> tribe.get_managers()[<User: tribe_user>, <User: admin>]#删除管理员>>> response = browser.post('/group/1/revoke/2/')>>> response.content'{"msg": "", "result": true}'#小组搜索>>> response = browser.get('/group/search/',{'search_text': 'china 3'})>>> response.context['tribes'][<Tribe: artist in china 3>]#删除组员>>> tribe.get_members()[<User: tribe_user>, <User: admin>]>>> tribe.get_managers()[<User: admin>]>>> response = browser.get('/group/1/del_tribe_user/3/')>>> response.content'{"msg": "not a tribe user.", "result": false}'>>> response = browser.get('/group/1/del_tribe_user/1/')>>> response.content'{"msg": "can\\\'t delete tribe creator", "result": false}'>>> response = browser.get('/group/1/del_tribe_user/2/')>>> response.content'{"msg": "delete tribe user successfully.", "result": true}'>>> Topic.objects.all()[<Topic: test topic>, <Topic: topic1>, <Topic: topic2>, <Topic: topic3>]#都是trib user>>> Topic.objects.all().creator<User: tribe_user>#no permission>>> browser.logout()>>> response = browser.post('/accounts/login/', {'username': 't_user', 'password': 'eeeee', 'remember':0})>>> response = browser.get('/group/topic/1/del_topic/')>>> response.status_code403#creator >>> browser.logout()>>> response = browser.post('/accounts/login/', {'username': 'tribe_user', 'password': 'eeeee', 'remember':0})>>> response = browser.get('/group/topic/1/del_topic/')>>> response.status_code302#管理员可以删除>>> Topic.objects.all().tribe.get_managers()[<User: admin>]>>> admin = User.objects.get(username='admin')>>> browser.logout()>>> response = browser.post('/accounts/login/', {'username': 'admin', 'password': 'eeeee', 'remember':0})>>> response = browser.get('/group/topic/2/del_topic/')>>> response.status_code302#有权限删除>>> t_user = User.objects.get(username='t_user')>>> t_user.user_permissions.all()[]>>> p = Permission.objects.get(codename="del_topic")>>> t_user.user_permissions.add(p)>>> t_user.save()>>> a = User.objects.get(username='t_user')>>> a.user_permissions.all()[<Permission: tribe | topic | Can delete tribe topics>]>>> a.has_perm('tribe.del_topic')True>>> browser.logout()>>> response = browser.post('/accounts/login/', {'username': 't_user', 'password': 'eeeee', 'remember':0})>>> response = browser.get('/group/topic/3/del_topic/')>>> response.status_code302"""
页: [1]
查看完整版本: doctest写测试非常爽:)