This commit is contained in:
chai2010
2015-12-16 10:55:14 +08:00
parent 3e80d25c15
commit c187ed90f8
6 changed files with 60 additions and 41 deletions

View File

@@ -1,11 +1,11 @@
### 11.2.5. 編寫有效的測試
多Go新人会惊异与它的极简的测试框架. 很多其他言的测试框架都提供了识别测试函数的机制(通常使用反射或元数据), 通过设置一些 setupteardown子函数来执行测试用例行的初始化或之的清理操作, 同时测试工具箱提供了很多似assert言, 比值, 格式化输出错误信息和停止一个识别的测试等辅助函(通常使用异常机制). 虽然这些机制可以使得测试非常简洁, 但是测试输出的日志却像火星文一般以理解. 此外, 虽然测试最终也会输出 PASS 或 FAIL 的告, 但是它提供的信息格式非常不利于代码维护者快速定位问题, 因为失败的信息的具体含义是非常患的, 比如 "assert: 0 == 1" 或 成的海量跟踪日志.
多Go新人會驚異與它的極簡的測試框架. 很多其他言的測試框架都提供了識彆測試函數的機製(通常使用反射或元數據), 通過設置一些 setupteardown子函數來執行測試用例行的初始化或之的清理操作, 衕時測試工具箱提供了很多似assert言, 比值, 格式化輸齣錯誤信息和停止一個識彆的測試等輔助函(通常使用異常機製). 雖然這些機製可以使得測試非常簡潔, 但是測試輸齣的日誌卻像火星文一般以理解. 此外, 雖然測試最終也會輸齣 PASS 或 FAIL 的告, 但是它提供的信息格式非常不利於代碼維護者快速定位問題, 因為失敗的信息的具體含義是非常患的, 比如 "assert: 0 == 1" 或 成的海量跟蹤日誌.
Go言的测试风格则形成鲜明对比. 它期望测试者自己完成大部分的工作, 定义函数避免重, 就像普通程那. 编写测试并不是一个机械的填充程; 一个测试也有自己的接口, 管它的维护者也是测试仅有的一个用户. 一好的测试不应该引发其他无关的错误信息, 它要清晰简洁地描述问题的症状即可, 有候可能需要一些上下文信息. 在理想情下, 维护者可以在不看代的情下就能根据错误信息定位错误产生的原因. 一好的测试不应该在遇到一点小错误就立刻退出测试, 它应该尝试报告更多的测试, 因此我可能从多个失败测试的模式中发现错误产生的律.
Go言的測試風格則形成鮮明對比. 它期望測試者自己完成大部分的工作, 定義函數避免重, 就像普通程那. 編寫測試並不是一個機械的填充程; 一個測試也有自己的接口, 管它的維護者也是測試僅有的一個用戶. 一好的測試不應該引發其他無關的錯誤信息, 它要清晰簡潔地描述問題的癥狀卽可, 有候可能需要一些上下文信息. 在理想情下, 維護者可以在不看代的情下就能根據錯誤信息定位錯誤產生的原因. 一好的測試不應該在遇到一點小錯誤就立刻退齣測試, 它應該嘗試報告更多的測試, 因此我可能從多個失敗測試的模式中發現錯誤產生的律.
面的断言函数比较两个值, 然生成一通用的错误信息, 停止程序. 它很方便使用也确实有效果, 但是当识别的时候, 错误时打印的信息乎是没有价值的. 它并没有为解决问题提供一很好的入口.
麪的斷言函數比較兩個值, 然生成一通用的錯誤信息, 停止程序. 它很方便使用也確實有效果, 但是噹識彆的時候, 錯誤時打印的信息乎是沒有價值的. 它並沒有為解決問題提供一很好的入口.
```Go
import (
@@ -26,7 +26,7 @@ func TestSplit(t *testing.T) {
}
```
从这个意义上说, 言函犯了早抽象的错误: 仅仅测试两个整数是否相, 而放了根上下文提供更有意义的错误信息的做法. 我可以根据具体的错误打印一更有值的错误信息, 就像下例子那. 测试在只有一次重的模式出现时引入抽象.
從這個意義上説, 言函犯了早抽象的錯誤: 僅僅測試兩個整數是否相, 而放了根上下文提供更有意義的錯誤信息的做法. 我可以根據具體的錯誤打印一更有值的錯誤信息, 就像下例子那. 測試在隻有一次重的模式齣現時引入抽象.
```Go
func TestSplit(t *testing.T) {
@@ -40,10 +40,10 @@ func TestSplit(t *testing.T) {
}
```
在的测试不仅报告了用的具体函数, 它的入, 和果的意; 且打印的真实返回的值和期望返的值; 并且即使断言失依然会继续尝试运行更多的测试. 一旦我们写了这样结构的测试, 下一步自然不是用更多的if语句来扩展测试用例, 我可以用像 IsPalindrome 的表驱动测试那样来准备更多的 s, sep 测试用例.
在的測試不僅報告了調用的具體函數, 它的入, 和果的意; 且打印的眞實返迴的值和期望返的值; 並且卽使斷言失依然會繼續嘗試運行更多的測試. 一旦我們寫了這樣結構的測試, 下一步自然不是用更多的if語句來擴展測試用例, 我可以用像 IsPalindrome 的錶驅動測試那樣來準備更多的 s, sep 測試用例.
的例子不需要外的助函, 如果如果有可以使测试代码更简单的方法我们也乐意接受. (我们将在 13.3 看到一 reflect.DeepEqual 助函.) 始一好的测试的关键是通过实现你真正想要的具体行为, 然后才是考虑然后简化测试代码. 最好的果是直接从库的抽象接口始, 针对公共接口编写一些测试函数.
的例子不需要外的助函, 如果如果有可以使測試代碼更簡單的方法我們也樂意接受. (我們將在 13.3 看到一 reflect.DeepEqual 助函.) 始一好的測試的關鍵是通過實現你眞正想要的具體行為, 然後纔是考慮然後簡化測試代碼. 最好的果是直接從庫的抽象接口始, 針對公共接口編寫一些測試函數.
**练习11.5:**表格驱动的技术扩展TestSplit测试, 打印期望的输出结果.
**練習11.5:**錶格驅動的技術擴展TestSplit測試, 打印期望的輸齣結果.