update tw

This commit is contained in:
chai2010
2015-12-18 10:53:03 +08:00
parent 510c741a6f
commit c66a96ee52
106 changed files with 864 additions and 864 deletions

View File

@@ -1,7 +1,7 @@
## 11.2. 測試函數
測試函數必導入 testing 包. 測試函數有如下的簽名:
測試函數必導入 testing 包. 測試函數有如下的簽名:
```Go
func TestName(t *testing.T) {
@@ -9,7 +9,7 @@ func TestName(t *testing.T) {
}
```
測試函數的名字必以Test開頭, 可選的後綴名必以大寫字母開頭:
測試函數的名字必以Test開頭, 可選的後綴名必以大寫字母開頭:
```Go
func TestSin(t *testing.T) { /* ... */ }
@@ -17,7 +17,7 @@ func TestCos(t *testing.T) { /* ... */ }
func TestLog(t *testing.T) { /* ... */ }
```
其中 t 參數用於報告測試失敗和附件的日誌信息. 讓我們頂一箇一箇實例包 gopl.io/ch11/word1, 隻有一函數 IsPalindrome 用於檢査一字符串是否從前後和從後前讀都一樣. (這實現對於一字符串是否是迴文字符串前後重復測試了兩次; 我們稍後會再討論這問題.)
其中 t 參數用於報告測試失敗和附件的日誌信息. 讓我們頂一個一個實例包 gopl.io/ch11/word1, 隻有一函數 IsPalindrome 用於檢査一字符串是否從前後和從後前讀都一樣. (這實現對於一字符串是否是迴文字符串前後重復測試了兩次; 我們稍後會再討論這問題.)
```Go
gopl.io/ch11/word1
@@ -36,7 +36,7 @@ func IsPalindrome(s string) bool {
}
```
在相的目下, word_test.go 文件包含了 TestPalindrome 和 TestNonPalindrome 兩測試函數. 每一都是測試 IsPalindrome 是否給齣正確的結果, 使用 t.Error 報告失敗:
在相的目下, word_test.go 文件包含了 TestPalindrome 和 TestNonPalindrome 兩測試函數. 每一都是測試 IsPalindrome 是否給齣正確的結果, 使用 t.Error 報告失敗:
```Go
package word
@@ -59,7 +59,7 @@ func TestNonPalindrome(t *testing.T) {
}
```
`go test` (或 `go build`) 命令 如果沒有參數指定包那將默認寀用噹前目對應的包. 我們可以用下的命令構建和運行測試.
`go test` (或 `go build`) 命令 如果沒有參數指定包那將默認採用當前目對應的包. 我們可以用下的命令構建和運行測試.
```
$ cd $GOPATH/src/gopl.io/ch11/word1
@@ -67,7 +67,7 @@ $ go test
ok gopl.io/ch11/word1 0.008s
```
還比較滿意, 我們運行了這程序, 不過沒有提前退齣是因爲還沒有遇到BUG報告. 一法國名爲 Noelle Eve Elleon 的用戶抱怨 IsPalindrome 函數不能識別 été.. 另外一來自美國中部用戶的抱怨是不能識別 A man, a plan, a canal: Panama.. 執行特殊和小的BUG報告爲我們提供了新的更自然的測試用例.
還比較滿意, 我們運行了這程序, 不過沒有提前退齣是因爲還沒有遇到BUG報告. 一法國名爲 Noelle Eve Elleon 的用戶抱怨 IsPalindrome 函數不能識別 été.. 另外一來自美國中部用戶的抱怨是不能識別 A man, a plan, a canal: Panama.. 執行特殊和小的BUG報告爲我們提供了新的更自然的測試用例.
```Go
func TestFrenchPalindrome(t *testing.T) {
@@ -84,9 +84,9 @@ func TestCanalPalindrome(t *testing.T) {
}
```
爲了避免兩次輸入較長的字符串, 我們使用了提供了有類似 Printf 格式化功能的 Errorf 函數來報錯誤結果.
爲了避免兩次輸入較長的字符串, 我們使用了提供了有類似 Printf 格式化功能的 Errorf 函數來報錯誤結果.
添加了這兩測試用例之後, `go test` 返迴了測試失敗的信息.
添加了這兩測試用例之後, `go test` 返迴了測試失敗的信息.
```
$ go test
@@ -98,11 +98,11 @@ FAIL
FAIL gopl.io/ch11/word1 0.014s
```
先編寫測試用例觀察到測試用例觸發了和用戶報告的錯誤相的描述是一好的測試習慣. 隻有這樣, 我們纔能定位我們要眞正解決的問題.
先編寫測試用例觀察到測試用例觸發了和用戶報告的錯誤相的描述是一好的測試習慣. 隻有這樣, 我們纔能定位我們要眞正解決的問題.
先寫測試用例的另好處是, 運行測試通常會比手工描述報告的處理更快, 這讓我們可以進行快速地迭代. 如果測試集有很多運行緩慢的測試, 我們可以通過隻選擇運行某些特定的測試來加快測試速度.
參數 `-v` 用於打印每測試函數的名字和運行時間:
參數 `-v` 用於打印每測試函數的名字和運行時間:
```
$ go test -v
@@ -121,7 +121,7 @@ exit status 1
FAIL gopl.io/ch11/word1 0.017s
```
參數 `-run` 是一正則達式, 隻有測試函數名被它正確匹配的測試函數纔會被 `go test` 運行:
參數 `-run` 是一正則達式, 隻有測試函數名被它正確匹配的測試函數纔會被 `go test` 運行:
```
$ go test -v -run="French|Canal"
@@ -137,11 +137,11 @@ FAIL gopl.io/ch11/word1 0.014s
```
然, 一旦我們已經脩復了失敗的測試用例, 在我們提交代碼更新之前, 我們應該以不帶參數的 `go test` 命令運行全部的測試用例, 以確保更新沒有引入新的問題.
然, 一旦我們已經脩復了失敗的測試用例, 在我們提交代碼更新之前, 我們應該以不帶參數的 `go test` 命令運行全部的測試用例, 以確保更新沒有引入新的問題.
我們現在的任務就是脩復這些錯誤. 簡要分析後發現第一BUG的原因是我們用了 byte 而不是 rune 序列, 所以像 "été" 中的 é 等非 ASCII 字符不能正確處理. 第二BUG是因爲沒有忽略空格和字母的大小寫導緻的.
我們現在的任務就是脩復這些錯誤. 簡要分析後發現第一BUG的原因是我們用了 byte 而不是 rune 序列, 所以像 "été" 中的 é 等非 ASCII 字符不能正確處理. 第二BUG是因爲沒有忽略空格和字母的大小寫導緻的.
鍼對上述兩BUG, 我們仔細重寫了函數:
鍼對上述兩BUG, 我們仔細重寫了函數:
```Go
gopl.io/ch11/word2
@@ -168,7 +168,7 @@ func IsPalindrome(s string) bool {
}
```
時我們也將之前的所有測試數據閤併到了一測試中的格中.
時我們也將之前的所有測試數據合並到了一測試中的格中.
```Go
func TestIsPalindrome(t *testing.T) {
@@ -205,17 +205,17 @@ $ go test gopl.io/ch11/word2
ok gopl.io/ch11/word2 0.015s
```
這種格驅動的測試在Go中很常見的. 我們很容易想格添加新的測試數據, 且後的測試邏輯也沒有冗餘, 這樣我們可以更好地完善錯誤信息.
這種格驅動的測試在Go中很常見的. 我們很容易想格添加新的測試數據, 且後的測試邏輯也沒有冗餘, 這樣我們可以更好地完善錯誤信息.
失敗的測試的輸齣不包括調用 t.Errorf 時刻的堆棧調用信息. 不像其他語言或測試框架的 assert 斷言, t.Errorf 調用也沒有引起 panic 或停止測試的執行. 卽使格中前的數據導緻了測試的失敗, 格後的測試數據依然會運行測試, 因此在一測試中我們可能了解多失敗的信息.
失敗的測試的輸齣不包括調用 t.Errorf 時刻的堆棧調用信息. 不像其他語言或測試框架的 assert 斷言, t.Errorf 調用也沒有引起 panic 或停止測試的執行. 卽使格中前的數據導緻了測試的失敗, 格後的測試數據依然會運行測試, 因此在一測試中我們可能了解多失敗的信息.
如果我們眞的需要停止測試, 或許是因爲初始化失敗或可能是早先的錯誤導緻了後續錯誤等原因, 我們可以使用 t.Fatal 或 t.Fatalf 停止測試. 它們必在和測試函數衕一箇 goroutine 內調用.
如果我們眞的需要停止測試, 或許是因爲初始化失敗或可能是早先的錯誤導緻了後續錯誤等原因, 我們可以使用 t.Fatal 或 t.Fatalf 停止測試. 它們必在和測試函數同一個 goroutine 內調用.
測試失敗的信息一般的形式是 "f(x) = y, want z", f(x) 解釋了失敗的操作和對應的輸齣, y 是實際的運行結果, z 是期望的正確的結果. 就像前檢査迴文字符串的例子, 實際的函數用於 f(x) 部分. 如果顯示 x 是格驅動型測試中比較重要的部分, 因爲衕一箇斷言可能對應不衕的錶格項執行多次. 要避免無用和冗餘的信息. 在測試類似 IsPalindrome 返迴佈爾類型的函數時, 可以忽略沒有額外信息的 z 部分. 如果 x, y 或 z 是 y 的長度, 輸齣一相關部分的簡明總結卽可. 測試的作者應該要努力幫助程序員診斷失敗的測試.
測試失敗的信息一般的形式是 "f(x) = y, want z", f(x) 解釋了失敗的操作和對應的輸齣, y 是實際的運行結果, z 是期望的正確的結果. 就像前檢査迴文字符串的例子, 實際的函數用於 f(x) 部分. 如果顯示 x 是格驅動型測試中比較重要的部分, 因爲同一個斷言可能對應不同的表格項執行多次. 要避免無用和冗餘的信息. 在測試類似 IsPalindrome 返迴佈爾類型的函數時, 可以忽略沒有額外信息的 z 部分. 如果 x, y 或 z 是 y 的長度, 輸齣一相關部分的簡明總結卽可. 測試的作者應該要努力幫助程序員診斷失敗的測試.
**練習 11.1:** 爲 4.3節 中的 charcount 程序編寫測試.
**練習 11.2:** 爲 (§6.5)的 IntSet 編寫一組測試, 用於檢査每操作後的行爲和基於內置 map 的集等價 , 後 練習11.7 將會用到.
**練習 11.2:** 爲 (§6.5)的 IntSet 編寫一組測試, 用於檢査每操作後的行爲和基於內置 map 的集等價 , 後 練習11.7 將會用到.
{% include "./ch11-02-1.md" %}