以前在大公司,寫完任何一個程式都要寫 php unittest,另外還有專職的測試工程師會寫 regression test,來用 firefox 摸擬使用者的某些行為。
本篇介紹一些我們使用的方法,歡迎大家討論或參考。
我們的習慣是,新產品在第二次上線的時候,一定要寫 test case。
為什麼是第二次上線呢?因為第一次上線太忙了... XD
另外第一次上線還會有非常多東西要修改,甚至要測什麼東西可能還搞不太清楚。
所以我留到第二次。(但還是有一些例外的)
phpunit:
- 以前在大公司寫這個,個人覺得意義不大。那時把 php template 寫成 class,然後再用 phpunit 去測試 html 結構。
- 我們這邊使用的是單純測試 php 邏輯,比如說美妝邦在爬文章時,有很多 filter 的邏輯,input和output很清楚,但裡頭邏輯很複雜。這種情況就把php寫成一個class,再用phpunit,一邊寫程式一邊測試。
使用 js 做 unittest:
- 我們還沒有開始測試任何的 js 程式。之後打算用單純的 try cactch 或是 onerror 的方式來直接抓取使用者端的 js 錯誤,然後發送一個 beacon (1x1的gif檔發送到server作紀錄),因為 js 邏輯太複雜了,這種方式簡單而且省人力成本。
- 我們用 js 的 unittest 來測試很多頁面的東西。相較於 phpunit 總是在安穩的測試環境跑,js unittest我們是可以在 production (上線的機器) 環境跑的,這才比較容易找得出問題。而且透過標準的 selector 可以更容易檢查 html 結構上的錯誤。
- 環境是這麼設的。
- 有一個頁面可以設置 internal cookie ,當設完 internal cookie 後,就可以就可以直接在線上的某個頁面跑 js 的 unittest
- 透過 /test-path/curl/ 直接在 production /dev 機器下 curl 指令抓網頁。因為我們有很多不同 domain 的站。
- 我們以前是用 yui unittest,最近發現qunit(jquery unit) 超簡單也超好用的。
例子
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; // 加了這個,js就要用比較嚴謹的方法來寫,比如,若你沒有宣告變數就直接使用,就會跳出錯誤 | |
// common function | |
var add_beta = function(url) | |
{ | |
if(location.href.indexOf('http://beta')!==-1) | |
return url.replace("http://", "http://beta."); | |
return url; | |
} | |
// cross domain,就像是 file_get_contents 一樣,這邊的作用就像是proxy | |
var get_content = function(uri) | |
{ | |
return get_data('/js-unit-test/curl/?url='+encodeURIComponent(uri)); | |
} | |
var get_data = function(uri){ | |
var html = ''; | |
$.ajax( | |
{ | |
url:uri, | |
async:false, | |
dataType:'text', | |
success: function(data){ html = data; } | |
}); | |
return html; | |
}; | |
module("List Pages"); | |
test("all", function(){ | |
var url = add_beta("http://tw.piliapp.com/"); | |
var html = get_content(url); | |
// 轉換成 jquery 的格式,用div包起來的原因是因為,這樣才抓得到第一層的element | |
html = $("<div>" + html + "</div>"); | |
ok($("article > div.item").size() === 20, "item number should be 20"); | |
}); | |