防禦性編碼和單元測試規則 二

2021-08-21 22:53:15 字數 2725 閱讀 3389

加強警戒(en garde)!

要記住,您的客戶對您的產品有與您不一樣的想法。他們會在乙個您的小組很可能從來也沒想到的 —— 或者至少是沒有可能測試的 —— 環境中安裝它。他們會以您從來沒有想到過的方法使用它,並以您意想不到的方法配置它。下面的列表有助於幫助您保證他們不會發怒:

驗證所有收到的引數的完整性(考慮如果您期待乙個陣列而傳遞來的是乙個null,但是您在索引陣列之前沒有檢查這種可能性時會發生什麼情況)。

考慮所有可能的錯誤情況並增加處理每種情況的**(您希望**得體地處理錯誤條件而不是堵塞它)。

對於那些未預料到的錯誤條件,加入乙個一般性的「捕獲所有」錯誤處理程式。

在適當的時候和地點使用常量。

在**各處加入跟蹤和日誌。

如果您的產品將翻譯為另一種語言,那麼保證您的**可以「支援」它。即使出現這種情況的機會很小,但是提前計畫總是好一些。修改**以使它提供支援是最容易產生缺陷的。下面是幾個您要考慮的與支援相關的問題:

還有,在**中使用大量斷言。

給您的**加上充分的 注釋。總之,您還記得在六個月前編寫那個方法時的想法嗎?一年後要修改您的**的某個人又會怎麼想呢?在我們提出的所有建議中,這一條可能是最重要的。

單元測試(防禦性測試技術)

在本文中,我們所說的 單元測試 是開發人員在自己的**正確編譯後、在交給功能測試小組之前進行的所有測試和分析。正如我們在 這只是乙個測試 中提到的,主動進行單元測試並 在測試時像一位測試者那樣思考(即,必須往壞處想、熱衷於破壞並喜歡惡作劇)是很重要的。下面是在單元測試時要記住的幾件事。

靜態**分析工具

為**建立「壓力條件」,如大量活動、慢連線的網路和所有您想到的可以將**推到極限條件的東西。

反覆進行同樣的步驟,然後:

對於陣列和快取,試著向陣列(或者快取)增加n個資料項,然後試圖刪除n+1

個項。關於時間的考慮?

如果操作「b」在操作「a」之前發生會怎麼樣?就算您 認為 它不會發生 —— 您能 使 它發生嗎?如果是的話,可以打賭您的客戶會使它發生的。最好現在找出來,而不是在修復成本更高、並聽到客戶報怨您的軟體質量糟糕之後再去做。

腳手架**

我們在前面 發現缺陷 中討論了腳手架**。如果是為自己的使用需要而建立的,一定要將它交給驗證工程師。可能您提供的腳手架**使他們可以很快地開始測試您的**,或者至少使他們更好地理解當其他元件存在時可以預期什麼。

如果您的產品有保護性的安全功能,那麼您必須測試它們。提供可以建立您想要防止的情況的腳手架**是很重要的:您必須能夠建立系統試圖防止的那種情況。

腳手架**的另乙個簡單例子是提供操縱佇列的**。如果您的產品使用佇列,那麼想像如果有乙個可以在執行時從佇列中增加或者刪除項、破壞佇列中的資料(以保證適當的錯誤處理)等等的工具會有多方便。

源**級除錯程式

使用源**級的除錯程式是進行徹底和成功的單元測試的關鍵方法。開發人員應該與他們的除錯程式共生死。不幸的是,對源**級的除錯程式的充分了解和使用是一種正在消亡的做法,儘管這些除錯程式的好處遠遠超過任何學習曲線。簡而言之,我們強烈鼓勵您全面學習一種除錯程式。下面是用源**級除錯程式對**進行單元測試的幾種方法。您可以:

認識您的驗證工程師

驗證工程師是測試知識的很好**。他們可以給您指出要測試什麼並幫助您了解可以在**中加入什麼以幫助他們測試(如**鉤子)。此外,您可以向他們展示如何使用您的腳手架**。他們還會很有興趣了解您認為在測試中哪些應該是自動化的 —— 如果您某些事情做了不止一遍,那麼他們也會。

開始測驗!

現在是進行小測試的時候了。讓我們看看您是否用心了。

問題您希望檢查乙個整數的值是否為 5。通常,要這樣編寫**:

if ( i == 5 ) then

不過,如果您對**進行「手指檢查」,並且把**寫成了下面這樣會出現什麼情況呢?

if ( i = 5 ) then

這個失誤是乙個缺陷,但是只有在執行時才能捕獲它 —— 可能需要相當的除錯努力才能找到它。編譯器會輕易放過您的**,那麼如何防止這種錯誤發生?

答案實際上有兩個答案:您可以使用一種上面描述的靜態**分析工具,並希望它有足夠的健壯性可以捕獲這種錯誤,也可以交換運算元以使常量位於左邊:

if ( 5 == i ) then

因為這種方法保證您可以在編譯**時立即捕捉到問題,所以它是首選的技術。雖然它看上去有些笨,但是**可以編譯並執行得很好。然而,當您「手指檢查」**時就可以立即看到好處了:

if ( 5 = i ) then

if ( returnstring == null )

如果您偶然將它「誤寫」成下面這樣會發生什麼呢?

if ( returnstring = null )

您可能不會得到想要的結果。而改用下面的方法您會得到與我們剛描述過的同樣的「編譯器保護」:

if ( null == returnstring )

結束語

為保持簡明扼要我們做了乙個相當簡潔的歸納:要麼現在去做,要麼以後花 多得多 的代價去做。換句話說,您在開發周期的早期在測試和預防**缺陷上花的時間越多,您在以後節省的時間和金錢就越多。這就是防禦性編碼的意義。它就是這麼簡單。

iOS 單元測試4 單元測試編碼規範

編寫單元測試與編寫工程 略有不同。我們需要準備資料,mock物件,呼叫工程api,驗證結果。而且一般測試 都會比工程 要大。就像real world testing with xctest一文中提到 目前為止,我們的編碼庫已經縱橫 190 個檔案和 18,000 行 達到了 544 kb。我們測試部...

單元測試中的 AAA 規則

在單元測試中通常包含3大部分的 他們是設定初始條件的 執行業務邏輯的 以及驗證執行結果是否正確的斷言 為了提高這些 的可讀性,讓 顯得清晰整潔,我們建議程式設計師按照 aaa 規則來寫單元測試的 aaa 分別 了單元測試中的3大部分 即 arrange,act,assert。比如我們有一段 它的作用...

壓力測試和單元測試

壓力測試 adb shell monkey p 包名 v 次數 單元測試 需要測試的方法 public class test 測試的 public class testz extends androidtestcase 1 繼承androidtestcase類 2 在androidmanifest....