2011年11月1日

GAE Unit Test

主要參考Local Unit Testing for Python
測試時會建立模擬的server,在記憶體中完成,不會更改到實際Dev環境或是DataStore
gaeunit - 用web呈現但未來似乎不易串接進CI,且目前沒有對測試頁面做權限控管

使用nosegae 0.1.9搭配gaetestbed - 目前已經慢慢整合到官方的SDK

安裝

$ sudo easy_install nose
$ sudo easy_install nosegae
$ sudo easy_install webtest
$ sudo easy_install gaetestbed


test檔
請以test為開頭,實際上是符合(?:^|[b_.-])[Tt]est
雖然文件說你可以使用--match來執行特定的test檔案 但是實際上測試就是會有ImportError

遇到ImportError問題的人非常多
有人test檔名有問題
有人webtest版本不正確
有人easy_install.pth預設路徑磁碟是小寫和abspath吐出來的大寫名稱不同
也有人沒有建立tests package(tests folder with empty __init__.py)

我自己是遇到google picasa API裡面一堆test檔有問題
使用--exclude和--ignore(文件說優先權最高) 但還是在第一次掃描的時後掃描到有問題
第一次掃描似乎無可避免
另外--gae-application這個參數也有問題,還是會找不到project
我認為這些東西原本應該是好的,但是因為太多外掛造成的Issue

找到比較穩的方法如下
在project root底下建立tests package
test file開頭使用test

project
|---- tests
|---- __init__.py
|---- test_file1.py
|---- test_file2.py

執行nosetests時,到project root下執行
避免使用--match, --exclude, --ignore, --gae-application來處理問題
可以使用-vv和--collect-only來debug

執行

nosetests --with-gae --gae-lib-root="/path/to/google_appengine" tests


之後就可以參考gaetestbed來寫test case

開始跑WebTestCase仍然遇到問題
如果python版本是2.4 2.5應該會遇到
ValueError: dictionary update sequence element #0 has length 1; 2 is required
如果python版本是2.6以上可能會有
AttributeError: 'unicode' object has no attribute 'items'

trace code發現webtest 1.3.2中app.py第1028行傳header給Cookie.py去做設定
這裡header已經是unicode,但是在Cookie.py中預期得到bytestring或是dict
我選擇對Cookie.py進行修正

if isinstance(rawdata, unicode):
rawdata = str(rawdata)


終於可以跑unit test了 好感動
有人可以教我oauth 2.0登入的web application如何做funcitonal unit test嗎?

額外名詞學習:
mock - 行為測試
stub - 結果測試