06單元測試

不寫測試的開發不是好程序員,我個人非常崇拜TDD Test Driven Development 的,然而可惜的是國內的程序員

都不太關注測試這一部分,這篇文章主要介紹下在Go語言中如何做單元測試和基準測試。

go test 工具

Go 語言中的測試依賴go test 命令。編寫測試代碼和編寫普通的Go代碼過程是類似的,並不需要學習新的語法。

規則或工具

go test 命令是一個按照一定約定和組織的測試代碼的驅動程序,在包目錄內,所有以——test,go 爲後綴名

的源代碼文件都是 go test 測試的一部分,不會被go build 編譯到最終的可執行文件中。

在 *_test.go 文件中有三種類型的函數,單元測試函數、基準測試函數和示例函數。

測試函數 函數名前綴爲Test 測試程序的一些邏輯行爲是否正確

基準函數 函數名前綴爲Benchmark 測試函數的性能

示例函數 函數名前綴爲Example 爲文檔提供示例

go test 命令會遍歷所有的*_test.go文件彙總符合上述命名規則的函數,然後生成一個臨時的main包用於

調用相應的測試函數,然後構建並運行,報告測試結果,最後清理測試中生成的臨時文件

Conytext 初識

Go1.7加入了一個新的標準庫context,它定義了 Context類型,專門用來簡化對於處理單個請求的多個goroutine之間

與請求域的數據,取消信號。截止時間等相關操作,這些操作可能涉及多個API調用。

對服務器傳入的請求應該創建上下文,而對服務器的傳出調用應該接受上下文。他們之間的函數調用鏈必須傳遞上下文,或者可以使用WithCancel WithDeadline 

WithTimeout 或WithValue創建的派生上下文,當一個上下文被取消時,它派生的所有上下文也被取消

Context接口

contexty.Context 是一個接口,改接口定義了四個需要實現的方法,具體簽名如下:

type Context interface {

  Deadline() (deadline time.Time, ok bool)

  Done() <- chan struct{}

  Err() error

  Value(key interface{}) interface{}

}

其中

Deadline 方法需要返回當前Context被取消的時間,也就是完成工作的截止時間deadline

Done方法需要返回一個Channel ,這個Channel會在當前工作完成或者上下文被取消之後關閉,多次調用

Done方法會範湖同一個Channel;

Err方法會返回當前Context結束的原因,它只會在Done返回的Channel被關閉時纔會返回非空的值;

如果當前的Context被取消就會返回Canceled錯誤;

如果當前Context超時就會返回DeadlineExceeded錯誤;

Value方法會從Context中返回鍵對應的值,對於同一個上下文來說,多次調用Value並傳入相同的Key

會返回相同的結果,該方法僅用於傳遞跨API和進程間跟請求域的數據;

Background() 和TODO()

Go內置兩個函數:Background()和TODO(),這兩個函數分別返回了一個實現了Context接口的background

和todo.我們代碼中最開始都是以這兩個內置的上下文對象作爲最頂層的partent context ,衍生出更多的子

上下文對象。

Background() 主要用於main函數,初始化以及測試代碼中,作爲Context這個樹結構的最頂層的Context,也就是

Context.

TODO() 它目前還不知道具體的使用場景,如果我們不知道該使用什麼Context的時候,可以使用這個

background 和 todo 本質上都是emptyCtx 結構體類型,是一個不可取消,沒有設置截止時間,沒有攜帶任何值得

Context。

With系列函數

此外,context 包中還定義了四個With系列函數。

WithCancel 

返回帶有新Done通道的父節點的副本。當調用返回的cancel函數或當關閉父上下文的Done通道時,將關閉返回上下文的Done通道,無論先發生什麼情況。

取消此上下文將釋放與其關聯的資源,因此代碼應該在此上下文中運行的操作完成後立即調用cancel

WithDeadline

返回父上下文的副本,並將deadline調整爲不遲於d,如果父上下文的deadline已經早於d,則WithDeadline(

parent,d)在語義上等同於父上下文。當截止日過期時,調用返回的cancel函數時,或者當父上下文的Done

通道關閉時,返回上下文的Done通道即將關閉,以最先發生的情況爲準。

取消此上下文將釋放與其關聯的資源,因此代碼應該在此上下文中運行的操作完成後立即調用cancel

WithTimeout

取消此上下文將釋放與其相關的資源,因此代碼應該在此上下文中運行的操作完成後理解調用

cancel,通常用於數據庫或者網絡連接的超時控制。

WithValue

返回父節點的副本,其中與key關聯的值爲val.

僅對api和進程間傳遞請求域的數據使用上下文,而不是使用它來傳遞可選參數給函數。

所提供的健必須是可以比較的,並且不應該是string類型或任何其他內置類型,以避免使用上下文在包之間

發生衝突。withValue 的用戶應該爲健定義自己的類型。爲了避免在分配給interface {} 時進行分配,上下文

健通常具有具體類型struct{} 。或者,導出的上下文關鍵變量的靜態類型應該是指針或接口。

使用Context的注意事項

推薦以參數的方式顯示傳遞Context

以Context作爲參數的函數方法,應該把Context作爲第一個參數。

給一個函數方法傳遞Context的時候,不要傳遞nil,如果不知道傳遞什麼,就是用context.TODO()

Context的Value相關方法應該傳遞請求域的必要參數,不應該用於傳遞可選參數

Context 是線程安全的,可以放心的在多個goroutine 中傳遞

Zookeeper

是一個分佈式的,開放源碼的分佈式應用程序協調服務,是Google的Chubby一個開源的

實現,它是集羣的管理者,監視者集羣中各個節點的狀態根據節點提交的反饋進行

下一步合理操作。最終,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章