mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-12-18 03:34:19 +08:00
回到简体
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
### 11.2.3. 白盒測試
|
||||
### 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%的存储配额之后将发送提醒邮件。
|
||||
|
||||
<u><i>gopl.io/ch11/storage1</i></u>
|
||||
```Go
|
||||
@@ -48,7 +48,7 @@ func CheckQuota(username string) {
|
||||
}
|
||||
```
|
||||
|
||||
我們想測試這個代碼,但是我們併不希望發送眞實的郵件。因此我們將郵件處理邏輯放到一個私有的notifyUser函數中。
|
||||
我们想测试这个代码,但是我们并不希望发送真实的邮件。因此我们将邮件处理逻辑放到一个私有的notifyUser函数中。
|
||||
|
||||
<u><i>gopl.io/ch11/storage2</i></u>
|
||||
```Go
|
||||
@@ -73,7 +73,7 @@ func CheckQuota(username string) {
|
||||
}
|
||||
```
|
||||
|
||||
現在我們可以在測試中用僞郵件發送函數替代眞實的郵件發送函數。它隻是簡單記録要通知的用戶和郵件的內容。
|
||||
现在我们可以在测试中用伪邮件发送函数替代真实的邮件发送函数。它只是简单记录要通知的用户和邮件的内容。
|
||||
|
||||
```Go
|
||||
package storage
|
||||
@@ -107,7 +107,7 @@ func TestCheckQuotaNotifiesUser(t *testing.T) {
|
||||
}
|
||||
```
|
||||
|
||||
這里有一個問題:當測試函數返迴後,CheckQuota將不能正常工作,因爲notifyUsers依然使用的是測試函數的僞發送郵件函數(當更新全局對象的時候總會有這種風險)。 我們必須脩改測試代碼恢複notifyUsers原先的狀態以便後續其他的測試沒有影響,要確保所有的執行路徑後都能恢複,包括測試失敗或panic異常的情形。在這種情況下,我們建議使用defer語句來延後執行處理恢複的代碼。
|
||||
这里有一个问题:当测试函数返回后,CheckQuota将不能正常工作,因为notifyUsers依然使用的是测试函数的伪发送邮件函数(当更新全局对象的时候总会有这种风险)。 我们必须修改测试代码恢复notifyUsers原先的状态以便后续其他的测试没有影响,要确保所有的执行路径后都能恢复,包括测试失败或panic异常的情形。在这种情况下,我们建议使用defer语句来延后执行处理恢复的代码。
|
||||
|
||||
```Go
|
||||
func TestCheckQuotaNotifiesUser(t *testing.T) {
|
||||
@@ -124,6 +124,6 @@ func TestCheckQuotaNotifiesUser(t *testing.T) {
|
||||
}
|
||||
```
|
||||
|
||||
這種處理模式可以用來暫時保存和恢複所有的全局變量,包括命令行標誌參數、調試選項和優化參數;安裝和移除導致生産代碼産生一些調試信息的鉤子函數;還有有些誘導生産代碼進入某些重要狀態的改變,比如超時、錯誤,甚至是一些刻意製造的併發行爲等因素。
|
||||
这种处理模式可以用来暂时保存和恢复所有的全局变量,包括命令行标志参数、调试选项和优化参数;安装和移除导致生产代码产生一些调试信息的钩子函数;还有有些诱导生产代码进入某些重要状态的改变,比如超时、错误,甚至是一些刻意制造的并发行为等因素。
|
||||
|
||||
以這種方式使用全局變量是安全的,因爲go test命令併不會同時併發地執行多個測試。
|
||||
以这种方式使用全局变量是安全的,因为go test命令并不会同时并发地执行多个测试。
|
||||
|
||||
Reference in New Issue
Block a user