Python论坛  - 讨论区

标题:[zeuux-python] [GAECamp] 我得GAE上面的Unittest总结

2008年12月24日 星期三 22:26

Zoom.Quiet zoom.quiet在gmail.com
星期三 十二月 24 22:26:57 CST 2008

好文章,发现,立即分享相关列表,,,

2008/12/24 Zoom. Quiet <zoom.quiet在gmail.com>:
> 2008/12/24 lincong.javatech在gmail.com <lincong.javatech在gmail.com>:
>> 呵呵 刚刚加入 虽然是北京的也来凑个热闹,发个我的文:P
>>
> 没有见颜色,,,在邮件中,,,
> 整理到 啄木鸟维基吧,,,
>
>> GAE上面的Unittest总结:
>> http://ihere.appspot.com/post/2465
>>
GAE上面的Unittest总结 [image: feedsky] <http://ihere.appspot.com/feeds/post/2465>

类别:GAE 开发 <http://ihere.appspot.com/category/GAE%20%E5%BC%80%E5%8F%91/1>  |
evertobe <evertobe在gmail.com>  | 写于2008‐十二月‐21 05:49  | 被锤击数:74  |
RSS<http://ihere.appspot.com/feeds/post/2465>

GAE上面的Unittest总结:
我是个推崇敏捷开发 重构 TDD 小步迭代 快速交付的 开发者,本来一直都用java来开发 , 最近迷上了python, google app
engine, django
一开始我就想python上面的敏捷开发应该是怎么样的, 那阵还真不太了解 碰了不少壁:-( 经过一段时间的总结在 现在慢慢找到python
gae上面开发的套路了, 觉得这个应该是GAE上开发以及unittest的较好实践了:P  特此发文分享:-)

参考:unit-tests-for-google-app-engine-apps<http://blog.appenginefan.com/2008/06/unit-tests-for-google-app-engine-apps.html>,
gaeunit <http://code.google.com/p/gaeunit/>, appengine
helper<http://code.google.com/p/google-app-engine-django/>

首先我想直接通过django的test 来测试gae上的app, 众所周知 appengine的mode层与django完全不同
这样其实直接运行test是不可取的
通过查阅这篇文章unit-tests-for-google-app-engine-apps<http://blog.appenginefan.com/2008/06/unit-tests-for-google-app-engine-apps.html>得知
:其实appengine 的开发sdk本身已经提供了很多api stub 来帮助我们写unit test.
其实主要的地方是在test的setup方法里面注册这些stub 以及设置必要的环境变量,
以我发的demo<http://ihere.appspot.com/post/2264>做个讲解

# coding=UTF-8
import unittest,os,urllib
from django.test.client import Client
#import the stubs, i.e. the fake datastore, user and mail service and
urlfetch
from google.appengine.api import apiproxy_stub_map
from google.appengine.api import datastore_file_stub
#from google.appengine.api import mail_stub
from google.appengine.api import urlfetch_stub
from google.appengine.api import user_service_stub
from google.appengine.api.memcache import memcache_stub

from django.utils.encoding import force_unicode,smart_str
from google.appengine.api import users
from django.test import TestCase

from google.appengine.ext.db.djangoforms import ModelForm
import unittest
from django.test.client import Client
from google.appengine.api import users
import logging
from models import *

#How I do gae test:-)
#1.
#using gaeunit: http://code.google.com/p/gaeunit/
#and need to fix a bug of Django : Ticket #5176
#http://code.djangoproject.com/ticket/5176

#2.
#using appengine_django_helper:
#
http://code.google.com/intl/zh-CN/appengine/articles/appengine_helper_for_django.html
#
http://appengineguy.com/2008/06/proper-unit-testing-of-app-enginedjango.html[GFW
blocked]
#run from cmd: manage.py test upload
#Here i use the 2nd way:P
#enjoy
class FileTest(unittest.TestCase):

    def setUp(self):
        # Start with a fresh api proxy.
        apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()

        # Use a fresh stub datastore.
        # From this point on in the tests, all calls to the Data Store, such
as get and put,
        # will be to the temporary, in-memory datastore stub.
        stub =
datastore_file_stub.DatastoreFileStub(u'myTemporaryDataStorage',
'/dev/null', '/dev/null')
        apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', stub)

        # Use a fresh stub UserService.
        apiproxy_stub_map.apiproxy.RegisterStub('user',
user_service_stub.UserServiceStub())
        os.environ['AUTH_DOMAIN'] = 'gmail.com'
        os.environ['USER_EMAIL'] = 'myself在appengineguy.com' # set to '' for
no logged in user
        os.environ['SERVER_NAME'] = 'testserver'
        os.environ['SERVER_PORT'] = '80'
        os.environ['USER_IS_ADMIN'] = '1' #admin user 0 | 1
        os.environ['APPLICATION_ID'] = 'appId'

        # Use a fresh urlfetch stub.
        apiproxy_stub_map.apiproxy.RegisterStub('urlfetch',
urlfetch_stub.URLFetchServiceStub())

        #User a memcache stub
        apiproxy_stub_map.apiproxy.RegisterStub('memcache',
memcache_stub.MemcacheServiceStub())

        # Use a fresh mail stub. mail stub have a conflit with the other api
by now in the real gae environment. so comment it.
#        apiproxy_stub_map.apiproxy.RegisterStub('mail',
mail_stub.MailServiceStub())

        # Every test needs a client. using django test client
        self.client = Client()

...


可以看到 蓝色部分是在注册gae的api stub (想深入研究 可以看看sdk 里面的dev_appserver.py 那里有具体的使用方法)
注意我使用了 Django的Test Client 来模拟Http请求  使用时候需要fix个bug 改django.zip里面的文件 如果使用我得
demo <http://ihere.appspot.com/post/2264> 的话是已经改好的:-)

接下来是个简单的test:

    def test_add_file(self):
        file=open('upload/testtxt.txt')

        response = self.client.post('/album/', {'file': file})
        file.close()
        self.failUnlessEqual(response.status_code, 302)

        returnResponse = self.client.get('/album/')
        self.assertTrue('testtxt.txt' in returnResponse.content)
        userFile=UserFile.all().filter("name =","testtxt.txt").get()
        self.assertTrue(userFile is not None)


向'/album/' 发起post请求  上传一个文件  并对response进行验证.

def tearDown(self):
        #For that we are using a temporary datastore stub located in the
memory,we don't have to clean up.
        pass


tearDown不需要做任何动作  因为最开始setup的时候 只是在内存中建立了一个临时datastore


这就是一个完整的 unit test 例子:-)

上面这个例子 在本地控制台 直接 manage test upload 可以直接运行 不需要启动gae的dev_appserver
但是通过一段时间的开发发现本地的sdk环境与gae的实际环境不完全相同.本机调试ok ,上传之后 ,可能在实际环境中还会有意料之外的bug:-(
有没有一种方式可以在实际的环境中进行测试呢? 老外已经看到这个了 并且有了解决方案 就是 :
gaeunit<http://code.google.com/p/gaeunit/>
它由http ajax驱动test的执行, 大家可以看我页面sidebar左下 lab 里面有个run test 就是这个
出于安全原因当然只有admin才可以执行. 下面说下怎么将django 本身的test与gae unit结合,并且不留重复code:-)
gaeunit 执行的时候会执行所有test文件夹下的test 我的demo
<http://ihere.appspot.com/post/2264>中test/test_upload.py
中只有一句话:
from upload.tests import FileTest

简单吧:P 而FileTest就是我们之前写的django unit test .这样集成之后这两种方式可以混用而且没有重复test code :-)
本地开发时候可以运行 manage test upload
而在gae 实际环境中又可以 直接在浏览器:http://yourhost/test
来执行gae unit test
每次看到这个都很高兴:-)




Enjoy!


 Posted by evertobe at 05:49 AM <http://ihere.appspot.com/post/2465>


-- 
http://zoomquiet.org
'''过程改进乃是催生可促生靠谱的人的组织!'''
Time is unimportant, only life important!
-------------- 下一部分 --------------
一个HTML附件被移除...
URL: <http://www.zeuux.org/pipermail/zeuux-python/attachments/20081224/37c94987/attachment.html>

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2024

    京ICP备05028076号