mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-12-25 14:28:58 +00:00
ch11: fix code path
This commit is contained in:
parent
0c1b9762d9
commit
c683de9b81
@ -5,8 +5,8 @@
|
||||
|
||||
讓我們爲 2.3.2節 的 echo 程序編寫一個測試. 我們先將程序拆分爲兩個函數: echo 函數完成眞正的工作, main 函數用於處理命令行輸入參數和echo可能返迴的錯誤.
|
||||
|
||||
<u><i>gopl.io/ch11/echo</i></u>
|
||||
```Go
|
||||
gopl.io/ch11/echo
|
||||
// Echo prints its command-line arguments.
|
||||
package main
|
||||
|
||||
@ -104,5 +104,3 @@ FAIL gopl.io/ch11/echo 0.006s
|
||||
錯誤信息描述了嚐試的操作(使用Go類似語法), 實際的行爲, 和期望的行爲. 通過這樣的錯誤信息, 你可以在檢視代碼之前就很容易定位錯誤的原因.
|
||||
|
||||
要註意的是在測試代碼中併沒有調用 log.Fatal 或 os.Exit, 因爲調用這類函數會導致程序提前退出; 調用這些函數的特權應該放在 main 函數中. 如果眞的有意外的事情導致函數發送 panic, 測試驅動應該嚐試 recover, 然後將當前測試當作失敗處理. 如果是可預期的錯誤, 例如非法的用戶輸入, 找不到文件, 或配置文件不當等應該通過返迴一個非空的 error 的方式處理. 幸運的是(上面的意外隻是一個插麴), 我們的 echo 示例是比較簡單的也沒有需要返迴非空error的情況.
|
||||
|
||||
|
||||
|
@ -11,9 +11,8 @@
|
||||
|
||||
下面的代碼演示了爲用戶提供網絡存儲的web服務中的配額檢測邏輯. 當用戶使用了超過 90% 的存儲配額之後將發送提醒郵件.
|
||||
|
||||
<u><i>gopl.io/ch11/storage1</i></u>
|
||||
```Go
|
||||
gopl.io/ch11/storage1
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
@ -52,9 +51,8 @@ func CheckQuota(username string) {
|
||||
|
||||
我們想測試這個代碼, 但是我們併不希望發送眞實的郵件. 因此我們將郵件處理邏輯放到一個私有的 notifyUser 函數.
|
||||
|
||||
<u><i>gopl.io/ch11/storage2</i></u>
|
||||
```Go
|
||||
gopl.io/ch11/storage2
|
||||
|
||||
var notifyUser = func(username, msg string) {
|
||||
auth := smtp.PlainAuth("", sender, password, hostname)
|
||||
err := smtp.SendMail(hostname+":587", auth, sender,
|
||||
@ -130,5 +128,3 @@ func TestCheckQuotaNotifiesUser(t *testing.T) {
|
||||
這種處理模式可以用來暫時保存和恢複所有的全局變量, 包括命令行標誌參數, 調試選項, 和優化參數; 安裝和移除導致生産代碼産生一些調試信息的鉤子函數; 還有有些誘導生産代碼進入某些重要狀態的改變, 比如 超時, 錯誤, 甚至是一些刻意製造的併發行爲.
|
||||
|
||||
以這種方式使用全局變量是安全的, 因爲 go test 併不會同時併發地執行多個測試.
|
||||
|
||||
|
||||
|
@ -19,8 +19,8 @@ func TestLog(t *testing.T) { /* ... */ }
|
||||
|
||||
其中 t 參數用於報告測試失敗和附件的日誌信息. 讓我們頂一個一個實例包 gopl.io/ch11/word1, 隻有一個函數 IsPalindrome 用於檢査一個字符串是否從前向後和從後向前讀都一樣. (這個實現對於一個字符串是否是迴文字符串前後重複測試了兩次; 我們稍後會再討論這個問題.)
|
||||
|
||||
<u><i>gopl.io/ch11/word1</i></u>
|
||||
```Go
|
||||
gopl.io/ch11/word1
|
||||
// Package word provides utilities for word games.
|
||||
package word
|
||||
|
||||
@ -143,8 +143,8 @@ FAIL gopl.io/ch11/word1 0.014s
|
||||
|
||||
針對上述兩個BUG, 我們仔細重寫了函數:
|
||||
|
||||
<u><i>gopl.io/ch11/word2</i></u>
|
||||
```Go
|
||||
gopl.io/ch11/word2
|
||||
// Package word provides utilities for word games.
|
||||
package word
|
||||
|
||||
@ -229,4 +229,3 @@ ok gopl.io/ch11/word2 0.015s
|
||||
{% include "./ch11-02-5.md" %}
|
||||
|
||||
{% include "./ch11-02-6.md" %}
|
||||
|
||||
|
@ -7,13 +7,10 @@
|
||||
|
||||
這些幫助信息中語句的覆蓋率是最簡單和最廣泛使用的. 語句的覆蓋率是指在測試中至少被運行一次的代碼占總代碼數的比例. 在本節中, 我們使用 `go test` 中集成的測試覆蓋率工具, 來度量下面代碼的測試覆蓋率, 幫助我們識别測試和我們期望間的差距.
|
||||
|
||||
The code below is a table-driven test for the expression evaluator we built back in Chapter 7:
|
||||
|
||||
下面的代碼是一個表格驅動的測試, 用於測試第七章的表達式求值程序:
|
||||
|
||||
<u><i>gopl.io/ch7/eval</i></u>
|
||||
```Go
|
||||
gopl.io/ch7/eval
|
||||
|
||||
func TestCoverage(t *testing.T) {
|
||||
var tests = []struct {
|
||||
input string
|
||||
@ -102,5 +99,3 @@ $ go tool cover -html=c.out
|
||||
不過兩個 panic 語句依然是紅色的. 這是沒有問題的, 因爲這兩個語句併不會被執行到.
|
||||
|
||||
實現 100% 的測試覆蓋率聽起來很好, 但是在具體實踐中通常是不可行的, 也不是值得推薦的做法. 因爲那隻能説明代碼被執行過而已, 併不意味着代碼是沒有BUG的; 因爲對於邏輯複雜的語句需要針對不同的輸入執行多次. 有一些語句, 例如上面的 panic 語句則永遠都不會被執行到. 另外, 還有一些隱晦的錯誤在現實中很少遇到也很難編寫對應的測試代碼. 測試從本質上來説是一個比較務實的工作, 編寫測試代碼和編寫應用代碼的成本對比是需要考慮的. 測試覆蓋率工具可以幫助我們快速識别測試薄弱的地方, 但是設計好的測試用例和編寫應用代碼一樣需要嚴密的思考.
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user