2015年2月3日 星期二

Learning how to learn(2)

你愛睡覺嗎?


(Credit: 55Laney69 cc by 2.0)


醒著的時候,腦中其實會產生很多有毒物質。研究發現,睡眠的時候腦細胞會收縮,腦細胞間的空間變大,讓腦脊髓液的流動更暢通,更容易代謝有毒物質。有毒物質如果沒有被排除一直累積在腦中,會讓你的無論是思考、學習、做決定都鈍鈍的。

2015年1月30日 星期五

Learning How to Learn(1)

Coursera 上有門非常好的課 learning how to learn,它由神經與認知科學出發,簡單介紹腦部的運作,再搭配實證研究結過,告訴你有效學習的方法。我想是因為有理論又有實證,裡面介紹的一些技巧其實以前也有聽過,但是都沒有這個課程裡講得有說服力。

短短四周的課,內容充實,既有知識性有有實用性。每週還有一些學者訪談,很能激發學習熱情。另外,我也推薦教育工作者或為人父母者從此課程獲得學習的知識,我相信對指導學生與孩子都會很有幫助。

我計劃用五篇文章左右來分享我從中學到的,也呼應課程中所說的『分享是最好的學習方法』

2014年12月5日 星期五

故事爸爸的十五分鐘

上週到國小一年級的女兒教室當故事爸爸,同時也有另外一位(應該是學務處的志工)故事媽媽,我們在早自習時段各講了一個故事給女兒班上的小鬼頭們聽。看到小鬼頭的反應,讓我很有想法。

首先上場的是故事媽媽,她講了一個海馬故事 —— 海馬爸爸和海馬媽媽生了一堆小海馬(這裡穿插了一些海馬知識的介紹,例如公海馬有育兒袋),其中一隻特別不愛練習變色(繼續穿插海馬小知識,海馬靠變色隱身在環境中躲避天敵),有一天大難來臨,海馬都被大魚吃了,但不愛變色的小海馬卻剛好躲在石堆裡睡覺沒被吃(!),還救出了全家,最後被海馬公主看上,稀哩呼嚕居然變成駙馬。


credit: snaulkter  CC 2.0

故事媽媽講得認真,長得又漂亮,連講帶演,最厲害的是她居然會模仿海馬游泳的樣子,我下巴都快掉下來了。小朋友的反應呢?還好而已,並不是很熱烈,有些人托腮,有些人打呵欠。我倒是沒看到有人吃雞腿和滑手機,還好還好!

為什麼?

因為海馬故事本身一點都不有趣啊!一個不有趣的故事,表演得再生動再誇張,也沒有辦法牢牢吸住小朋友。



我講的是『好想吃榴槤』,我女兒指定我講的故事 —— 有隻天真的小老鼠沒吃過榴槤,於是跑去問他的好朋友獅子、山羊、河馬榴槤倒底是什麼味道。獅子、山羊、河馬根本沒吃過,但都胡謅一通,硬是說榴槤超好吃,吃起來像芭樂鳳梨與西瓜。小老鼠聽得傻了,口水都流出來了,於是...................... 哈哈,賣個關子。

這本故事書確實也是我最喜歡的一本,故事就是有趣,圖畫又可愛,每次看到裡面河馬張大嘴巴大喊:「當然吃過榴槤啊!味道跟芭樂一樣!」我就覺得他真的是我小時候認識的某個朋友,沒心機的不懂裝懂又愛吹牛,但很可愛。看到最後一頁大結局,又會覺得這群動物真的太好笑太可愛了,好想每一隻都抓起來捏一捏。

小朋友的反應最直接,每一雙眼睛都牢牢地盯著我,露出好奇的神情,到最後的開懷大笑,這就是故事吸引力的差別,

畢竟故事本身有趣才是一切!


 credit: Hafiz Issadeen CC 2.0


2014年12月4日 星期四

AngularJS Unit Testing

最近換工作以來突然寫Web UI的機會變多了,原本的UI是陳年老code了,多用 jquery 搭配各式 componant 再加上各種 event handler 刻出來的,程式裡到處都在操作 DOM,頗難維護。之前在W公司時就看到專業的前端工程師使用 backbone.js 這種 MVC framework,當時就頗想偷師。現在就趁此機會撥亂反正一下,把 MVC 架構帶入目前產品中,讓 UI code 更好維護。

我研究了一下最近常聽到的 javascript MVC framework,依照“要用就要用最潮的技術”的原則引領之下,選擇了 angularjs 這個 model-view-whatever framework。先不論 angularjs 與其他 framework 相比有哪些優缺點,光看 tutorial 裡每一節都有 unit test 該怎麼寫就讓身為 TDD 愛用者的我小高潮了。

接下來就分享一下我這一個月來學習 angularjs 與 unit test 的心得感想吧。

angularjs + jasmine + karma


javascrip unit testing 的工具非常多,因為太多了,我都採用 angularjs tutorial 裡面使用的 tool: jasmine test framework + karam test runner.

Test Framework - jasmine


jasmine 是個 javascript testing framework,在單元測試中的角色如同寫 c++ / java 時用到的 cppunit 與 junit 一樣,讓你方便地寫出 test cases、組合成 test suite、比較預期結果與實際結果、回報執行結果。jasmine 比較特別的是用 it() 來定義 test case,引導你要把要測試的行為用完整句子寫出來。如果你的作文能力不錯的話,真的能把 test case 寫得像文章一樣好讀。

describe('FizzBuzz', function() {

    it('outputs the original number if the input number is not multiple of 3 or 7,
        function() {
            expect(fizzbuzz(1)).toBe("1");
            expect(fizzbuzz(2)).toBe("2");
            expect(fizzbuzz(4)).toBe("4");
    });

    it('outputs "fizz" if the input number is multiple of 3', function() {
            expect(fizzbuzz(3)).toBe("fizz");
            expect(fizzbuzz(6)).toBe("fizz");
            expect(fizzbuzz(9)).toBe("fizz");
    });

    it('outputs "buzz" if the input number is multiple of 7', function() {
            expect(fizzbuzz(7)).toBe("buzz");
            expect(fizzbuzz(14)).toBe("buzz");
            expect(fizzbuzz(28)).toBe("buzz");
    });

    it('outputs "fizzbuzz" if the input number is multiple of 7 and 3',
       function() {
            expect(fizzbuzz(21)).toBe("fizzbuzz");
    });
});

我的作文能力還OK嗎?

Test Runner - karma


以前用 C++ / C# / java 時都比較不會注意到 test runner 這件事,反正你用什麼 testing framework,就是要用專用的 test runner,IDE 裡也許有內建,所以無感於 test runner 的存在。但是做 UI javascript testing 時有個大不同,UI 上的 javacript 是要丟到瀏覽器上面跑的,怎麼丟給瀏覽器?要丟給哪些瀏覽器?Test runner 就是幫我們搞定這些事情。

我這次選用的 Karam test runner 很厲害,可以跟各種 testing framework 與瀏覽器整合,無論用 jasmine、mocha 或是其他 framework,要在 chrome、firefox、safari、ie 執行測試,karma 都可以搞定。karma 還有個很貼心的服務—偵測到檔案變更時它會自己重新執行所有 test cases,對 TDD 更方便了。

karam 一次幫我搞定四個瀏覽器,非常盡責



安裝 karma 請參考這裡,安裝完可以用 karma init 產生預設的 config 再來修改。

module.exports = function(config) {
  config.set({

    basePath: '../',

    // 使用 jasmine test framework
    frameworks: ['jasmine'],

    // 哪些 file 要載入測試。陷阱注意:順序很重要
    files: [
        'test/phantomjs-fix.js',
        'js/angular.min.js',
        'test/angular-mocks.js',
        'js/volume_dialog.js',
        'test/spec/*spec.js'
    ],

    // 產生 progress 訊息與 junit report
    reporters: ['progress', 'junit'],

    // junit report 檔案名稱
    junitReporter: {
        outputFile: 'test-results.xml',
        suites: ''
    },

    port: 9876,

    colors: true,

    logLevel: config.LOG_INFO,

    autoWatch: true,

    // 要在哪些瀏覽器上面執行
    browsers: ['Chrome', 'Firefox', 'Safari', 'PhantomJS'],

    singleRun: false
  });
};


設定裡頭有兩個陷阱,一是一定要把 angular-mock.js 加入到 files 裡,二是 files 是有順序性的,angular.js 在前,angular-mock*.js 要在後。搞這個就搞死我了。

Angularjs Unit Test 到底怎麼寫


angularjs developer's guide 浮光掠影的解釋了 unit testing 要怎麼做。但看完一定沒法馬上動手寫,最有效的方法還是去找人做一遍給你看,哈!啪一下額頭就是 youtube,這個 Introduction to angularjs unit testing 很適合。


整合到 CI - 沒有 GUI怎麼辦?


寫了測試就一定要整合到 CI 裡,否則就是白寫。ㄟ .... 只是測試都是跑在瀏覽器上面,我的 CI server 沒有 GUI 沒有瀏覽器怎麼辦?就是 PhantomJS 出場的時機了。PhantomJS 也是個以WebKit 為基礎的瀏覽器,只是他不真的把畫面呈現出來,若想操作存取網頁,必須透過 PhantomJS 提供的 javascript API。

要用 PhantomJS 執行 unit test,除了安裝 PhantomJS 外,還需要 karma-phantomjs-launcher。執行 karma 時可以用 karma start --browsers PhantomJS 指定只要用 PhantomJS

用 PhantomJS 執行測試通常也很容易撞到這座牆:PhantomJS 不支援 Function.bind() method。解法就是自己實做吧!


// phantomjs-fix.js
// phantomJs does not support bind().
// See https://github.com/ractivejs/ractive/issues/679
Function.prototype.bind = Function.prototype.bind || function (thisp) {
    var fn = this;
    return function () {
        return fn.apply(thisp, arguments);
    };
};

整合到 CI - 產生 junit report


最後,在安裝 karma-junit-reporter 並設定產生檔案的名稱就能產出xml report.

2014年1月3日 星期五

純 C 的 unit testing framework - CUnit

最近我轉職去寫純 C 的程式,太多年沒接觸 C  了,好多 C  語言奇器淫巧都不熟悉,有種時光倒流回到10年前當菜鳥工程師的感覺。雖然工具不熟,但是寫程式的好習慣還沒忘記,我一開工就立刻找找有什麼純 C 的 unit testing framework  可以使用。

我找到了個 CUnit。CUnit  文件相當精要,掃過一遍之後就知道它合用了。真正用起來果然也容易上手。唯一碰到的小討厭就是和 Jenkins CI  整合的問題 - 廣大的 JUnit / NUnit  / 甚至是 JsUnit 用戶都有專屬 plugin  分析 unit test 產生的 XML 測試結果,可以直接在  Jenkins  上面看到哪些 test case 失敗以及測試歷史紀錄,但是CUnit 太小眾了,當然沒有人為他寫 Jenkins plugin。

好險我找到了個好東西 - xUnit plugin,他可以把很多稀奇古怪 unit test framework (例如:AUnit / UnitTest++ / boost test / pascal unit ...)產生的 XML
測試文件轉成最常用支援最多的 JUnit 格式,再由,再由 JUnit plugin 去分析統計結果!雖然 CUnit  太小眾了,讓 xUnit  不知如何轉換(靠!有比 Pascal  Unit 小眾嗎?),但是 xUnit 可以讓使用者自訂 xml style sheet  來轉換 XML,哈,那擴充支援 CUnit 就是小菜一疊而已了。

我寫好的 CUnit -> JUnit xml style sheet 在  GitHub 上,歡迎取用。

2013年2月1日 星期五

關於占用騎樓


做生意的店家佔用騎樓這種小事,我想大家看到都麻木了吧!尤其當店家不是第一天佔地為王,而是已經佔用了好幾年,甚至是整條街都這樣搞,如果還有人覺得「跟相關單位反映」會有用的,那他也太天真了。

我雖然很天真,但也沒那麼天真。只是每次看到那幾個把整個廚房搬到騎樓的店家、把地上弄得油油膩膩腳踩上去就快黏住的店家、把冰箱料理台都放在騎樓的店家... 心裡真是非常不愉快。算是死馬當活馬醫兼發洩一下而已,於是我上了新北市政府的網站,點進了市長信箱,反映此些商家的違規情況並附上幾張照片。猜想一周後會大概會有個「本府已行文OO單位處理,若對本案仍有其他意見或疑問,惠請與XXX聯絡,將竭誠為您服務與說明」類似的制式回應吧。

一周後真的收到非常類似的回應,而且還有一句「市長非常重視」。嘿嘿,朱市長有重視耶~~ 最好是這樣。

再一周,ㄟ,這幾家店開始施工了,是擴大營業嗎?又再過三天,原來他是在裝修廚房,真的是把鍋碗瓢盆料理台菜刀切菜板搬回店裡面了。又過了三天,經過店面的時候聽見幾家店的老闆聚在一起,居然是在討論到底是誰去檢舉的!!!(哈)

不可思議啊!透過市長信箱檢舉長久當路霸的店家居然有用,真得太出乎意料了!身為市長頭家的我,第一次有當頭家的快意。警察局也頗有效率,雖然仍是打一鞭才會動一下有告才有理(我就不相信轄區派出所不知道這條路上占用騎樓嚴重,只是沒人檢舉他樂的不處理而已),但有處理就真的有效果,也比我以為得好多了。

從前我看到破壞生活環境的事物多是心理忿忿不平而已,但經過這次的檢舉成功,更讓我心中的抓耙子檢舉魂再次燃燒(是的,我從小就是個愛告狀兼打小報告令同學討厭的人),哈哈,現在你們得小心我這個超級抓耙子了!

2012年6月21日 星期四

王品餐後感


上周末到王品為岳父大人慶生,回家之後著實不舒服至今,忍不住說說它的壞話...

分量實在太大  大到不舒服

所有人到過王品的人都學會這項求生技能:主菜上了就要直接打包帶走,免得撐死 。可是.... 幹.... 嘛要餵我吃這麼多呢?當我看到岳父點的超大一塊台塑牛排上桌時,心裡只覺得好險沒選這道主菜,否則撐死的就是我。王品就不能把分量弄少一點、但更精緻一點嗎?

另外,隔壁是男生幫女友慶生,我非常為那位精心準備的男生感到惋惜,他準備了花和禮物,在王品吃個午餐卻身心受到極大負荷(至少胃腸啦),接下來要去薇閣其他安排好的行程勢必受到影響。


吃完牛排  喉嚨痛到現在

吃完王品第二天起我喉嚨就開始痛,雖然時間順序不代表因果關係,算我賴到王品頭上好了,我猜極有可能因為牛排燒烤的火候太烈,傷害了我細嫩的喉嚨。#@%^$#@$%.... (喉嚨太痛胡言亂語中)


總之,王品的後座力時在驚人,沒甚麼意外我應該不太敢再去嘗試了。

2012年6月17日 星期日

關於一個熱血開發團隊

要離開前公司時,我部門的大老闆問我到底新公司是哪裡吸引我?我說我很期待跟一群好漢一起坐個新產品,雖然面對很多不確定 - 客戶到底存不存在? 產品概念能不能被接受? - 但是我們一起學習,一起解決,互相幫忙,完成困難的任務,這非常很吸引我。

大老闆聽完後說:「你追求的東西好虛幻」,而我馬上就臉紅了....

※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※

換到新公司的第一個月,我獨自開發 Windows 產品的後端程式,進展得相當穩定,卻是穩定的慢。看著其他 team 的 burndown chart 真的是狂燒,我的卻是蝸牛慢慢爬,又沒有 team member 可以靠一下,心中真的是相當焦慮又無助。

某天,突然同事「大支」跑來找我,跟我說他手上的工作快要到一個段落了,即日起自願加入 Windows 的陣營一起用 C# 開發,而他本來都是寫 python 和 C/C++ , 完全沒寫過 C#!我問他為什麼會想轉職,他說他兩個月前剛來公司的時候也是自己一個人開發,感覺真的很糟,他了解這種苦悶,所以才想過來幫忙。

大支看了一篇 從 C++ 到 C# 注意事項後就上工了。兩個月後我們的 release 了我們產品的第一個版本,回想起孤軍奮戰的那一個月,真是慶幸有大支的見義勇為。

今年二月底賴瑞加入 Windows 團隊後,我們變得更像個精實的作戰部隊了 ─ 接到任務後我們可以拆解成數個獨立目標,和 Product Owner 討論執行優先順序後,大支、賴瑞、我又一起反覆討論該程式該怎麼實作然後再去分工。兩個讓我覺得最棒的地方就是


  1. 我們是共同設計程式 : 我們會討論到應該用哪些 class 用哪種 pattern 加哪些 handler 送出那些 event 物件之間怎麼樣call來call去都討論得很深入,不是「就地分贓」式的儘把工作分三塊然後老死不相往來直到程式爆炸的那一天! 設計定案後再把該做的工作分成三塊,由最菜的開始先開始認領要做哪一塊。
  2. 我們互相幫忙 : 發現了 bug 永遠會有人搶著把他解掉,先完成工作的人會隨時來問有沒有地方需要他的幫忙 。
這樣熱血合作的開發團隊,幾乎就是我心目中理想的團隊了!(成員全是宅男扣5分 應該要搭配兩位腐女才對....)

※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※ ※

回到前公司大老闆的 comment:「你追求的東西好虛幻」。是的,「熱血合作團隊」對大老闆那種職位的人來說已經是太遙遠的過去而沒有任何意義了。但對我來說,在一個「熱血合作團隊」中工作很重要,它能讓我安定並發揮最大的力量。

事隔快一年再度想起大老闆的 comment 還是會讓我有點臉紅,但這次是因為能夠身處一個讓我熱血澎湃的團隊而潮紅。

2012年4月22日 星期日

還是關於 TDD, 以及 Mock

自從上次 TDD 寫得太差造成 team member 的困擾之後, 我最近寫程式都嚴格遵守 Dependency Inversion Principle ─ 當我的 class 需要用到 database 或 要呼叫 remote service 等等的外部資源時, 我會根據此 class 的需求訂出 interface, 這樣一來我的 class 就不會和外部資源有直接的關聯 ─ unit test 時就寫個 fake object 來 implement 這個 interface.

例如這個很奇怪的例子, 我要寫的 function 是能把所有傳入的 integer 加總然後存到某個 Database 裡. 下面這個 unit test 就是在驗證這件事. 這個例子中我特地寫了一個 FakeDB  ─ 他會去紀錄 caller 到底傳了甚麼 value 進來到 SavedSum 這個 property 裡  ─  而 unit test 就是驗證  SavedSum 果然如預期就是 1+2+3+4.


[TestMethod]

public void TestThattSumOfAllParamsAreSavedToDB()

{

      FakeDB db = new FakeDB();

      Class1 c1 = new Class1(db);

      c1.sum(1, 2, 3, 4);



      Assert.AreEqual(1 + 2 + 3 + 4, db.SavedSum);

}



class FakeDB : DBInterface

{

    public int SavedSum { get; private set; }

    public SaveValue(int value)

    {

        this.SavedSum = value;

    }

}



interface DBInterface

{

    void SaveValue(int value);

}



class Class1

{

    private DBInterface db;

    public Class1(DBInterface db)

    {

        this.db = db;

    }



    public void SumToDB(params int[] values)

    {

        int total = 0;

        foreach (int value in values)

            total += value;



       this.db.SaveValue(total);

    }

}



但是建立這些 FakeDB, FakeServer, FakerService, FakeFileSystem, Fake巴拉巴拉是很耗時耗力又很難 maintain 的, 最好得方法是改用專們產生 fake object 的 mock framework 來幫忙.

下面就是使用 Moq 來建立 mock object 的例子. 簡單很多吧!


public void TestThattSumOfAllParamsAreSavedToDB()

{

      Moq.Mock<DBInterface>db = new Moq.Mock<DBInterface>();

      db.Setup(x => x.SaveValue(1+2+3+4)).Verifiable();



      Class1 c1 = new Class1(db.Object);

      c1.sum(1, 2, 3, 4);



      db.VerifyAll();

}





我的小感想: 我用 TDD 好一陣子了但一直沒用 mock framework, 所以造成我過去寫 unit test 時, 都是硬做自己的 fake object. 寫太多 fake object 就覺得好費時又好費力, 最後變成乾脆不切這些 interface 了, 直接在 test fixture 裡設定 db / http server 之類的, 因為覺得這樣反而比寫 fake object 還快. 最終的結果就是如之前提到的反而造成同事困擾. 現在我會用 mock framework 了, 又開始感覺到 TDD 的順暢感跟爽度了. TDD 使用者們, 若你還沒開始用 mock framework, 快去找一個吧!

2012年4月8日 星期日

關於 user story 的二三事

這兩週我所屬的 happy cloud team 在整理 user story 時學到了點東西, 野人獻曝一下

一定要用完整句子寫下 user story


學習過 user story 怎麼寫的人, 一定知道有些泛用 pattern 常為人所推薦, 例如:


但真正寫起來, 常常會簡化成這樣子 (姑且稱之"關鍵字串"好了):

  • remove user on web site
  • remove user on app
  • user session expired

寫"關鍵字串"真的比寫完整的一句話來得快, 但它致命的缺點其實是會浪費更多時間去解釋這組關鍵字串到底要做甚麼.

選擇題 1.  Remove user on web site 意思是?

  1. A system admin can kill an account on web site
  2. A user can kill his own account on web site
  3. 以上皆非
  4. 以上皆是

選擇題 2.  remove user on app 是說

  1. A user can kill his account using foobar app
  2. A user can make foobar app "un-remember" an account so that he won't see this account in the user list anymore.
  3. 以上皆非

看似平淡的一組"關鍵字串"卻有很多的解釋空間, 一個 iteration planning 免不了要從十數個到數十個 story 中挑一些出來做, 好幾次我們就遇到, 好不容易解釋完這一堆"關鍵字串"究竟要做甚麼, 挑出了個位數的 story 確認要排入 iteration 中了, 當要把 story 再拆成 tasks 時還是會聽到 「ㄟ... 這個 story 究竟是要做甚麼啊?」不過是兩小時的 planning meeting 就會發生這樣的事, 要是整個 product backlog 都用關鍵字串, 那全部解釋完 product owner 大概人也老了.

一定要用中文


同事們和我英文都不差, 但中文都比英文好更多. 描述同樣一個 user story, 用中文我們可以描述得更簡潔更精準更有效率, 既然如此, 那何直接不用中文撰寫 user story? 唯一提醒的是, 有些詞彙也許平常就慣用英文, 例如專業術語甚麼的, 那就不用太費力全翻成中文了, 像台灣霹靂火般的中英夾雜也是種美, 畢竟達到溝通的目的才是我們要的.

中文還有另一個優勢, 同樣的字數, 中文比英文夾帶更多資訊量. 用中文寫同一個 story 本來就會更短, 更容易寫在一張 7.5x7.5 的便利貼上, 甚至字可以寫大一點, 眼睛比較舒服, 這也算好處之一吧 :)

2012年3月25日 星期日

失敗的單元測試



我一向習慣用 TDD 來寫程式, 也很自豪寫出的程式品質還不賴, 尤其是用TDD開發完成後一定會順便產出一堆 unit test, 我以為若是有另一位開發者中途加入, 他一定很容易看懂我的程式, 既有的 unit test 也能幫助他確認沒有把程式改壞, 上手負擔會比較輕. 但是最近新進弟兄賴瑞的遭遇, 讓我知道我錯了...

賴瑞修改程式, 改變了某個 class 後 unit test 就無法通過了. 這是預期中的結果, 因為 unit test 也要跟著改變才會符合最新的 class 行為. 賴瑞很讚, 不囉嗦馬上就去改我寫的 unit test. 但也馬上遇到問題了, unit test 的 code 實在太難懂了, 他花一天把程式改完, 卻花了兩天修改 unit test...

我原以為是好東西的 unit test 卻變成賴瑞的絆腳石... 這這這..這到底是怎麼一回事?

賴瑞: "單元測試不夠單元"

一個好的 unit test 應該是自成一體, 簡單幾個步驟設定, 驗證一個結果. 但以我寫出的某個 unit test 為例, 要先設定 http server 依序傳回四個回應, 又要設定 mongo db 裡面的兩個 collection 要含有某 document, 驗證的東西又複雜無比, 難怪賴瑞看到眼睛痛.

這是 unit test 的寫得不好嗎? 是, 而且主體程式寫得也糟, 反應在 unit test 上就是這個樣子. 如果我的主體程式沒有直接 用 HttpRequest class 跟 http server 溝通, 而是透過某個 remote interface 跟 http server 要資料, 那 unit test 中就可以用 mock object 來代替 http server, 同理也可套用到 mongo db 上. 若是我好好遵照這個原則, unit test 一定簡單易讀易改多了, 每個 test 少個 30行程式碼吧.

unit test 的程式碼也是程式碼

希望 unit test 也易讀易懂易維護, 那對待 unit test 程式碼也要像一般的程式碼一樣. 寫一般程式的時候, 只要 copy & paste 程式碼, 腦中警鈴就會響起 -

有重複的程式碼, 這是萬惡根源, 等等要 refactor!

但copy & paste unit test 時, 這警鈴卻昏迷了, 於是我的 unit test 越來越可怕...

我寫一般程式的時候, function 命名都還蠻計較的, 會儘量想個名實相符的東西. 在命名 test function 時我卻滿偷懶的, 有時會寫出這樣的 function 名 - testUploadHandler2..... (烏鴉飛)

My bad may bad my bad .....

武器越大隻, 後座力也越大

TDD 的愛用者, 若你也跟我一樣會偷懶不把 dependency 用 interface 區隔, 不注意 unit test 程式碼的品質, 那別人修改你的程式的時候會遇到更大的困難, 因為除了程式碼難改, unit test 更難改. 慎之 慎之

2011年9月23日 星期五

我的TDD經驗(1)

從T社換到I社之後,一直在一個三人團隊做研究計畫。我們三個很早就說好儘量互相協助,包含寫程式也一起 pair programming,並利用test driven development(TDD)。我一直以來都是用TDD,另外兩位同事只是久聞TDD之名,不曾見過其人,所以當我使用各種技巧(讓本以為無法測試的程式變得可以測試、從很簡單的小功能寫成完整功能、...)寫出程式的時候,同事臉上隱約出現不可置信+恍然大悟的表情。

話說TDD我也是有一段漫長的自學過程...

2011年8月29日 星期一

ASUS WL530g 狂掉封包

ASUS 無線AP WL530g 是個老產品了,之前封存了好多年,最近才又拿出來用。果然,一用就讓我回憶起當初為何要封存它了。

2011年8月3日 星期三

Linux kernel coding style (下)

13. 列印 kernel 訊息

kernel開發者喜歡被大家看成是個受過教育的人,所以字要拼對,才能製造這種好印象。不要用一些跛腳的字眼,像是"dont",要用"do not" 或是 "don't"。訊息文字要扼要 清楚 精確。

kernel訊息文字結尾不需要句點。

列印數字的時候加上括號(%d)是毫無意義的,應該避免。

在linux/device.h中有專為driver提供的巨集,可以方便的印出適合訊息文字,如dev_err() dev_warn() dev_info()。要印出與driver無關的訊息,可以用linux/printk.h中的pr_debug()或是pr_info()。


2011年8月1日 星期一

幼稚園的畢業生感言

今天我才知道,大部分幼稚園的畢業生感言是用英文說的。當然,我說的是台灣台北的幼稚園,不是美國紐約的幼稚園。

2011年7月28日 星期四

Linux kernel coding style (中)

7. 從單一出口離開function


雖然有些人打死不用goto,但在kernel裡goto還是很好用的,尤其是goto到function最後統一處理些資源回收的工作。另外:

  • 無條件執行的statement容易理解
  • 減少nesting
  • 很容易新增exit point,減少錯誤的機會
  • 幫助compiler作些最佳化處理

2011年7月26日 星期二

Linux kernel coding style (上)

小弟最近為了這個新硬體,加了一個linux kernel module並改寫了arch/powerpc下的一些code,嘗試要把修改的code送回公司的repo裡。結果寫得太差,光是coding stlye的因素就被maintainer修改了快超過500行,沒有被maintainer直接踢回來是他心地善良。於是我花了點時間看 linux coding style 的文件,並把重點摘要於此,希望能讓初次踏入linux kernel裡的人很快了解這個最最最基本的東西。

2011年7月15日 星期五

應該要有個寫作計畫...

好久沒更新網誌,雖然除了我本人以外沒有其他讀者,但佔著茅坑不拉屎也是不好的。

其實心中是有寫作的題材,說出來給大家過過乾癮吧,例如

  • 從台牌T公司換到國際牌I公司的心路歷程
  • 從寫C# application換成寫linux kernel driver的奮鬥經驗
  • 從創意競賽看T公司與I公司的差別
  • 如何克服中年發福
  • 吃到蟑螂的經驗如何引發一個創業夢想
看到這馬上想按下訂閱按鈕了吧!不過,這一年來生活真的是太安逸了,晚上九點半就睡覺了,不像以前一樣動不動就搞到三更半夜,真的安逸到沒時間更新啊...


2010年9月9日 星期四

TCP checksum

For some reason I needed to write a TCP checksum program and google helped me find a sample code here: http://www.netfor2.com/tcpsum.htm . Unfortunately, I found the code is not completely correct. My fix is as below: