This commit is contained in:
chai2010
2015-12-14 11:31:28 +08:00
parent 44532b45b5
commit 7b4e9340f8
7 changed files with 82 additions and 82 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) {
@@ -198,24 +198,24 @@ func TestIsPalindrome(t *testing.T) {
}
```
的新测试阿都通了:
的新測試阿都通了:
```
$ 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.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" %}