顯示具有 testing 標籤的文章。 顯示所有文章
顯示具有 testing 標籤的文章。 顯示所有文章

2015年5月24日 星期日

JavaScript 測試 framework 評估小記

找了一下 javascript unit test 的 framework, 看了一陣子, 還是很久以前試過的 QUnit 最順眼, 載入一個 JS, 一個 CSS 檔就可以用了, 語法也簡單 (或著說比較習慣, BDD 風格看起來頗囉唆的)。

一開始不小心找到牛刀 Karma (是 test runner 不是 test framework), 糊里糊塗的裝來用, 看看預設用的 Jasmine, 還有 Jasmine, Mocha 和 QUnit 的比較文 (前兩者是 BDD 風格)。順便得知可搭配 PhantomJS 作 headless browser 測試。那天真的需要 Karma 時再來用吧。或是直接找個 QUnit + PhantomJS 的 runner, 大概也可滿足下一層級的需求。

參照這幾篇應該可以順利裝好 Karma。用Ubuntu 12.04 的話, 需要先手動升級 npm 至新版, 才能成功安裝 Karma。

雖然不會去用牛刀級的 framework, 看牛刀級的 framework 可以得知生態圈的全貌以及相關的熱門套件, 也是不錯的入門方法。

2010年10月11日 星期一

簡單的 mock 使用情境

今天在寫新功能時, 又陷入小小的苦惱。我要寫一個小函式, 這個函式會依參數從資料庫取出資料, 並依參數決定做那些操作, 再傳回操作完的結果。函式本身需求明確不複雜, 但有不少組合情況要處理好, 有 unit test 比較保險。

在開始 TDD 前, 我得先決定如何準備 fixture (輸入資料)。大概有兩種選擇:
  1. 規劃好目標函式的測試情境, 準備測試用的資料庫, 塞對應的資料進去。
  2. 使用 Mock (我用 pymox)
配合 Django TestCase 和 ORM 操作, 塞入測試資料已簡單許多, 不用自己產生一個同 schema 空的資料庫, 並在每個 test case 前先清空資料, 也不用自己下 SQL 填資料, 所以實作門檻已低了不少。但是仍有幾個問題:
  1. 當測試資料有 relation 時, 要多塞不少相關資料。
  2. 要規劃清楚那些案例需要那些資料。規劃完後, 也需要寫註解畫個表格之類的, 不然很難了解測試資料內容。即使畫了表格, 也不太直覺易懂。
  3. 日後發現新 bug 或改功能時, 不容易修改這堆測試資料。
最讓我受挫的是, 寫完後很難閱讀和維護, 測試案例一多, 根本沒興趣慢慢讀輸入資料的細節。其它像是和外部資源綁在一起、實作目標函式時得先寫相依函式等議題, 在這個例子裡到是沒那麼嚴重。
這回我改試著用 Mock, 將目標函式的介面寫成大概如下的形式:
def target_function(arg1, arg2, getter=db.some_function):
    ...
db 是我另開的模組, 用來放包著 SQL 操作的函式。getter 指向真正用的函式, 測試時則視測試案例傳不同的 mock objects。
使用 Mock 的話, 準備測試資料變得很容易, 而且直接寫明目標函式如何和這些資料互動, 不用看資料庫的資料想像它轉換後的資料。要加測試案例時簡單許多, 不用思考如何在不同表格組出前置資料, 再用這些資料經由資料庫操作轉成中間資料給目標函式用。整體評估下來, 為了測試而多加參數 getter 是很划算的設計, 在註解裡註明一下 getter 的用意即可。

用 Mock 帶來的問題則是:
  1. 視使用的方式, 對目標函式的實作細節需有不同深度的理解。像是 getter 被呼叫幾次, 傳入那些參數。若程式有部份是別人寫的, 需要另外時間讀原本已被隱藏的細節。 
  2. 目標函式改變使用 getter 的方式時, 也需更新準備 mock 的測試程式。
  3. 無法保證目標函式正確, 實際使用目標函式時會有正確成果, 因為 getter 有可能出錯。導致有可能要另測 getter。相對來說, 直接存取資料庫的例子, 不測 getter 的風險較小。
換個角度來看, 測試程式使用 Mock 相當於切開和資料庫的連繫, 卻增加和 getter 操作的連繫。

2010年8月23日 星期一

nosetests 的用法

將之前寫過的東西複製過來備忘。


安裝方式: easy_install nose。
寫 unittest 時,管理 test suit 是件很瑣碎又易犯錯的事,相信很多人會想說,能不能跑個程式,自行搜集目錄下全部的測試碼並自動執行。沒錯,大家的心聲 nose 聽到了!這裡直接用例子說明 nose 的使用方式,詳細說明請見《An Extended Introduction to the nose Unit Testing Framework 》
  • 執行目前目錄下所有測試:
    1
    
    nosetests
  • 只執行 package PKG 下的 module MOD 內的測試:
    1
    
    nosetests PKG.MOD
  • 只執行 package PKG 下的 module MOD 內的 test case CLS 的測試 (注意 test case 前接得是冒號):
    1
    
    nosetests PKG.MOD:CLS
  • 執行目前目錄下所有測試並附上子目錄 pkg1、pkg2 的 Code coverage 資訊:
    1
    
    nosetests --with-coverage --cover-package=pkg1,pkg2 --cover-erase
  • 不要執行 slow_test.py:
    1
    
    nosetests -e slow_test.py
  • 使用四個 CPU 平行執行測試:
    1
    
    nosetests --processes=4
  • 只執行上回失敗的測試:
    1
    
    nosetests --failed
–with-coverage 需要先裝 coverage;–process 得另裝 package multiprocessing ( easy_install multiprocessing ),相關說明詳見 Multiprocess: parallel testing
另外,若要讓 nose 跳過物件 A 的測試,就在程式裡寫上
1
A.__test__ = False
比方若不想測模組 mod,就在 mod.py 裡寫上
1
__test__ = False

2010年5月25日 星期二

JavaScript 雜項心得

之後大概沒機會繼續玩 JavaScript, 整理一下之前看過的東西。

主要是看 Douglas Crockford 寫的文件。過去一直排斥學 JavaScript, 這回終於開始學了。沒想到意外地有趣, 感謝 Douglas Crockford 賣力地為它澄清, 讓我有機會重新認識它。

JavaScript

必讀文件:
  • coding convention
  • Google Tech Talk: JavaScript, the good parts。半小時而已, 看完立即明白 JavaScript 的問題, 避開它們後 JavaScript 其實是很美很強大的語言。
  • JsLint 的說明並試一試。可以協助記得 coding convention, 後來到是沒什麼在用。若有需長期維護的程式, 再拿來用吧。JsLint 可以幫忙列出函式內變數的可視範圍, 像是 global / closure / local, 頗方便的。
Douglas Crockford 寫了一些好文件, 下面是我看過覺得頗受用的幾篇:
另外就是讀他寫的書: JavaScript, the good parts。可惜我空閒時間花完了, 沒翻幾頁。之後有機會再來好好讀一讀。

jQuery

其實大部份時間都在寫 jQuery, 不過懂 JavaScript 語法的話, 寫起來比較順手, 不會被 JavaScript 的語法卡住。jQuery 真是我用過最容易上手功能又強大的函式庫。
  • jQuery 教學 - 基礎篇: 附許多例子, 大概掃一遍就能上工啦。
  • ericsk 寫的 tutorial: 有完整的例子可以跟著做。
  • 官網的 CSS Selector 文件: 要能活用 jQuery, 第一步就要能熟用 CSS Selector 選出目標物件。
  • jQuery 參考手冊: 官網文件寫得很清楚, 也有附範例碼。若要找函式名稱, visualjquery 也很方便, 可以快速濾出可能的函式。
  • jQuery UI 和 jQuery Tools 將 CSS, HTML 和 JavaScript 包好, 方便使用。像是附月曆輸入日期的 input tag, 或是 progress bar 等。
再來就是掃一遍 jQuery API, 或是視需求查一下相關的文件, 比方用 even / odd 可以一行搞定 table 奇偶列不同 css class。用 eq / index 可以找到列表中特定的元件。

QUnit

QUnit 是 jQuery 為了 unit test 而寫的函式庫。用法就是寫個 html 載入 QUnit 的 js、css, 就可以藉由瀏覽器讀網頁來執行 unit test 並將結果輸出在網頁裡。
  • 簡單易懂的例子。
  • 官網有不少例子可以參考, 像 fx.js 的寫法挺漂亮的, 用 jQuery 建出 test fixture 而不用綁在 html 上測。
若寫了不少 QUnit 想在 terminal 上執行, 可以透過 js-test-driver 執行。它只是一個 test runner, 有提供 QUnit 的 adaptor, 這樣就能用 terminal 跑 Java 程式, 透過一個執行中的瀏覽器自動跑 unit test。我是看 Miško Hevery 推薦才試用的, 只是我的 JavaScript 沒多到需要這麼測, 寫了一些 QUnit 測完較複雜的核心後, 就沒在用了。大多情況還是在 Firebug console 裡試成就就貼到 JavaScript 程式裡。待下次寫 JavaScript 時, 再來多挑戰用 TDD 開發。

Firebug

我一開始用 Chrome Developer Tools, 不過和 Firebug 交替用一陣子後, 感覺還是 Firebug 比較好用。像 DOM navigation 和調整 CSS 的部份 Firebug 好用多了。除之前在 CSS 心得提到的影片外, 再看《3 分鐘學會用 firebug 除錯》, 用 console.log() 輸出物件, 在 Firebug DOM 裡觀看細部資訊, 相當方便。

備忘

2010年3月28日 星期日

3/20 和 Scott 閒聊的隨手記

以下列出上週末和 Scott 聊到的東西, 大部份都是 Scott 在講啦, 真是大雜燴啊...

Software

  • Scott 想在 ReviewBoard 按 "ship it" 後照 Linux kernel 社群的習慣, 自動加上 "sign-off-by SOMEBODY", 或是接收對方的 commit。fcamel 提到或許可用 plugin 的方式在 ship it 後接自己操作, 既然都是 python code, 做起來應該不會太難。後來 Scott 查到目前 ReviewBoard 尚無這個功能 (VMWare 內部有, 但和公司 infrastructure 合得太密切, 不能 open source)。短期內不會有這功能。
  • Scott 展示 virt-manager, 和其它家 VMware 比起來, 特色是零設定。裝好 guest OS 後, 會自動設個 domain name 給 guest OS, 於是 guest OS 和 host OS 之間可以用 domain name 連來連去。不足之處是只支援 Linux OS。Ubuntu 上也有, 不過標示成實驗性套件
  • Scott 展示 Remobo, 一個強大的 VPN 軟體。用法和 Skype 差不多, 兩台機器各註冊一個帳號, 互加 「buddy」, 兩者就可以透過 Remobo 中央伺服器指派的區域 IP (7.x.x.x) 互連 。號稱什麼牆都能穿, 看起來滿方便的。而且在 Windows、各家 Linux和 Mac 上都能執行!

Profiler

  • Scott 展示如何用 sysprof 做 profiling。sysprof 是 sampling-based 的 profiler, Scott 說它簡單易用。如果作 embedded 產品,需要在產品上紀錄 profile, 拷貝回開發機器分析的話,還是 oprofile 較好。未來則可能是 perf 的天下。這還是我第一次看到 sampling-based 的 profiler。對這些東西沒有概念, 鴨子聽雷。
  • 承上, 跑 profiler 時需要有 debug info 才能找到細節, 要另外裝含 debug info 的 package。rpm 和 dpkg 都有提供含 debug info 的 package, 。在 Ubuntu 下就是安裝 X-dbg, 比方說 package "python" 的 debug info package 是 "python-dbg"。
  • 承上, 這些 debug info package 不是另外提供一套編譯時有含 debug 訊息的東西, 而是一開始就編好有含 debug 訊息的套件, 再把它拆成 X 和 X-dbg 兩份。X 裡的二進位檔有記錄 debug 資訊要去那裡找。

Testing

  • fcamel 提及近來寫測試的一些心得, 沒聊太深。待有更多經驗後我會寫到 fcamel.twbbs.org 上。
  • fcamel 打算翻譯 "Why are we embarrassed to admit that we don’t know how to write tests?", 已取得原作者許可。Scott 依自己翻譯的經驗, 說「信雅達」三者難以兼顧, 先取雅和達吧。
  • fcamel 聊到 top-down 和 bottom-up 進行 TDD 的思維不同, top-down 時使用 mock 是很有趣的體驗。發覺像 Scott 這類 system-based engineer 似乎不怎麼喜歡 OOP 搞出的一堆新名詞。印象中 Linus 也常開炮轟 C++, 網路上不少討論的文章。

Sharing

  • Scott 建議 fcamel 可以直接到自己常用的 open source 上看看有沒有什麼 issue / bug 可以解, 這樣比較容易找到可以做的事。這建議滿實用的, 比自己用用發現問題更能找到事做。等手邊雜事做完、翻完一篇別人寫的技術文後, 就來試看看吧。
  • Scott 希望 fcamel 可以多放些技術心得到 ITRS Wiki, 但 fcamel 依過去的經驗, 覺得放 blog 比較容易被 Google 搜到, 並且方便討論。過去 fcamel 曾架過 web 個人站、wiki, 觀察它們和 blog 的使用情況, 結論是 blog 較易傳播資訊。
  • fcamel 分享自己玩 micro blog、blog、wiki 和觀察 Google Analytics 的心得。micro blog 又比 blog 更易集中討論。而且從 Google Alert 觀察到 Google 近來索引 micro blog 的速度愈來愈快。plurk 上發的文章, 剛開始是一兩月後才建立索引, 現在已是隔天就建入索引。

Others

  • Scott 展示 cross compiling for Windows on Linux。操作看起來比想像中簡單許多, 不過對我這種一定有灌 Windows 來打 Game 的人來說, 暫時沒這種需求。
  • Scott 推薦用Academic Earth 練英聽, 這個站搜集名大學的課程影片。我稍微看了一下, 有不少有趣的課, 可惜沒附字幕。Scott 另外推薦用 audible.com 買有聲書來聽。這等我功力更高後再來試吧。
  • fcamel 聊到最近 Joel 寫了一系列 Mercurial 教學文, 而且還做得很精美! 好奇 Joel 打什麼主意。聽 Scott 說才知道 Joel 的公司最近在賣 Kiln, 一個含 web 介面的 Mercurial server。

2010年1月17日 星期日

用 code.InteractiveConsole() 協助除錯

這篇提供一段程式說明如何讓執行中的程式收到 signal 後叫出 interactive console, 很實用的技巧。對我來說, 用在 unit test fail 時正好。

若比對的資料稍微複雜, 看到 test failed 後還是不明白錯在那裡。這時可以進入互動模式, 方便察看相關變數, 就像用 debugger 觀察局部變數一樣。只要在程式裡這麼寫:
import code
code.InteractiveConsole(locals=locals()).interact()
就能叫出 interactive console, 接著就可隨意觀察啦。

若有裝 ipython 的話, 用 ipython 更方便, 還支援 code completion:
import IPython;
IPython.Shell.IPShellEmbed()()

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...