mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-12-19 04:04:20 +08:00
make
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
### 11.2.3. 白盒測試
|
||||
|
||||
|
||||
一个测试分类的方法是基于测试者是否需要了解被测试对象的内部工作原理. 黑盒测试只需要测试包公开的文档和API行为, 内部实现对测试代码是透明的. 相反, 白盒测试有访问包内部函数和数据结构的权限, 因此可以做到一下普通客户端无法实现的测试. 例如, 一个饱和测试可以在每个操作之后检测不变量的数据类型. (白盒测试只是一个传统的名称, 其实称为 clear box 会更准确.)
|
||||
一個測試分類的方法是基於測試者是否需要了解被測試對象的內部工作原理. 黑盒測試隻需要測試包公開的文檔和API行為, 內部實現對測試代碼是透明的. 相反, 白盒測試有訪問包內部函數和數據結構的權限, 因此可以做到一下普通客戶端無法實現的測試. 例如, 一個飽和測試可以在每個操作之後檢測不變量的數據類型. (白盒測試隻是一個傳統的名稱, 其實稱為 clear box 會更準確.)
|
||||
|
||||
黑盒和白盒这两种测试方法是互补的. 黑盒测试一般更健壮, 随着软件实现的完善测试代码很少需要更新. 它们可以帮助测试者了解真是客户的需求, 可以帮助发现API设计的一些不足之处. 相反, 白盒测试则可以对内部一些棘手的实现提供更多的测试覆盖.
|
||||
黑盒和白盒這兩種測試方法是互補的. 黑盒測試一般更健壯, 隨着軟件實現的完善測試代碼很少需要更新. 它們可以幫助測試者了解眞是客戶的需求, 可以幫助發現API設計的一些不足之處. 相反, 白盒測試則可以對內部一些棘手的實現提供更多的測試覆蓋.
|
||||
|
||||
我们已经看到两种测试的例子. TestIsPalindrome 测试仅仅使用导出的 IsPalindrome 函数, 因此它是一个黑盒测试. TestEcho 测试则调用了内部的 echo 函数, 并且更新了内部的 out 全局变量, 这两个都是未导出的, 因此它是白盒测试.
|
||||
我們已經看到兩種測試的例子. TestIsPalindrome 測試僅僅使用導齣的 IsPalindrome 函數, 因此它是一個黑盒測試. TestEcho 測試則調用了內部的 echo 函數, 並且更新了內部的 out 全侷變量, 這兩個都是未導齣的, 因此它是白盒測試.
|
||||
|
||||
当我们开发TestEcho测试的时候, 我们修改了 echo 函数使用包级的 out 作为输出对象, 因此测试代码可以用另一个实现代替标准输出, 这样可以方便对比 echo 的输出数据. 使用类似的技术, 我们可以将产品代码的其他部分也替换为一个容易测试的伪对象. 使用伪对象的好处是我们可以方便配置, 容易预测, 更可靠, 也更容易观察. 同时也可以避免一些不良的副作用, 例如更新生产数据库或信用卡消费行为.
|
||||
噹我們開發TestEcho測試的時候, 我們脩改了 echo 函數使用包級的 out 作為輸齣對象, 因此測試代碼可以用另一個實現代替標準輸齣, 這樣可以方便對比 echo 的輸齣數據. 使用類似的技術, 我們可以將產品代碼的其他部分也替換為一個容易測試的僞對象. 使用僞對象的好處是我們可以方便配置, 容易預測, 更可靠, 也更容易觀察. 衕時也可以避免一些不良的副作用, 例如更新生產數據庫或信用卡消費行為.
|
||||
|
||||
下面的代码演示了为用户提供网络存储的web服务中的配额检测逻辑. 当用户使用了超过 90% 的存储配额之后将发送提醒邮件.
|
||||
下麪的代碼演示了為用戶提供網絡存儲的web服務中的配額檢測邏輯. 噹用戶使用了超過 90% 的存儲配額之後將發送提醒郵件.
|
||||
|
||||
```Go
|
||||
gopl.io/ch11/storage1
|
||||
@@ -50,7 +50,7 @@ func CheckQuota(username string) {
|
||||
}
|
||||
```
|
||||
|
||||
我们想测试这个代码, 但是我们并不希望发送真实的邮件. 因此我们将邮件处理逻辑放到一个私有的 notifyUser 函数.
|
||||
我們想測試這個代碼, 但是我們並不希望發送眞實的郵件. 因此我們將郵件處理邏輯放到一個俬有的 notifyUser 函數.
|
||||
|
||||
```Go
|
||||
gopl.io/ch11/storage2
|
||||
@@ -76,7 +76,7 @@ func CheckQuota(username string) {
|
||||
}
|
||||
```
|
||||
|
||||
现在我们可以在测试中用伪邮件发送函数替代真实的邮件发送函数. 它只是简单记录要通知的用户和邮件的内容.
|
||||
現在我們可以在測試中用僞郵件發送函數替代眞實的郵件發送函數. 它隻是簡單記録要通知的用戶和郵件的內容.
|
||||
|
||||
```Go
|
||||
package storage
|
||||
@@ -110,7 +110,7 @@ func TestCheckQuotaNotifiesUser(t *testing.T) {
|
||||
}
|
||||
```
|
||||
|
||||
这里有一个问题: 当测试函数返回后, CheckQuota 将不能正常工作, 因为 notifyUsers 依然使用的是测试函数的伪发送邮件函数. (当更新全局对象的时候总会有这种风险.) 我们必须修改测试代码恢复 notifyUsers 原先的状态以便后续其他的测试没有影响, 要确保所有的执行路径后都能恢复, 包括测试失败或 panic 情形. 在这种情况下, 我们建议使用 defer 处理恢复的代码.
|
||||
這裡有一個問題: 噹測試函數返迴後, CheckQuota 將不能正常工作, 因為 notifyUsers 依然使用的是測試函數的僞發送郵件函數. (噹更新全侷對象的時候總會有這種風險.) 我們必鬚脩改測試代碼恢復 notifyUsers 原先的狀態以便後續其他的測試沒有影響, 要確保所有的執行路徑後都能恢復, 包括測試失敗或 panic 情形. 在這種情況下, 我們建議使用 defer 處理恢復的代碼.
|
||||
|
||||
```Go
|
||||
func TestCheckQuotaNotifiesUser(t *testing.T) {
|
||||
@@ -127,8 +127,8 @@ func TestCheckQuotaNotifiesUser(t *testing.T) {
|
||||
}
|
||||
```
|
||||
|
||||
这种处理模式可以用来暂时保存和恢复所有的全局变量, 包括命令行标志参数, 调试选项, 和优化参数; 安装和移除导致生产代码产生一些调试信息的钩子函数; 还有有些诱导生产代码进入某些重要状态的改变, 比如 超时, 错误, 甚至是一些刻意制造的并发行为.
|
||||
這種處理模式可以用來暫時保存和恢復所有的全侷變量, 包括命令行標誌參數, 調試選項, 和優化參數; 安裝和移除導緻生產代碼產生一些調試信息的鈎子函數; 還有有些誘導生產代碼進入某些重要狀態的改變, 比如 超時, 錯誤, 甚至是一些刻意製造的並發行為.
|
||||
|
||||
以这种方式使用全局变量是安全的, 因为 go test 并不会同时并发地执行多个测试.
|
||||
以這種方式使用全侷變量是安全的, 因為 go test 並不會衕時並發地執行多個測試.
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user