2008-09-11 61 views
12

this question的代碼讓我覺得測試用例和斷言語句

assert(value>0); //Precondition 
if (value>0) 
{ 
    //Doit 
} 

我從來不寫if語句。斷言是足夠的/所有你可以做。 「早崩潰,死機經常」

CodeComplete狀態:

  • 斷言語句使應用程序正確
  • 的,如果測試使得應用強大的

我不認爲您已通過更正無效輸入值或跳過代碼使應用程序更健壯:

assert(value >= 0); //Precondition 
assert(value <= 90); //Precondition 
if(value < 0)   //Just in case 
    value = 0; 
if (value > 90)  //Just in case 
    value = 90; 
//Doit 

這些更正是基於您對外界做出的假設。 只有調用者知道你的函數有什麼「有效的輸入值」,並且他在調用你的函數之前必須檢查它的有效性。

套用CodeComplete: 「現實世界的程序成爲太亂了,當我們僅僅依靠斷言」。

問:我錯了,stuborn,愚蠢,太不守...

+0

我同意你的意見。斷言的全部內容是在測試過程中執行完整性檢查,這些檢查在生產中執行起來太昂貴。它們的功能與例外根本不同。 – Galik 2017-09-11 09:04:17

回答

10

的問題只信任斷言,是他們可以在生產環境中被關閉。引述維基百科的文章:

大多數語言允許斷言來啓用或禁用全局 和 有時獨立。斷言 通常在開發期間啓用 ,並在最終測試期間被禁用,並且 發佈給客戶。不是 檢查斷言,避免成本 評估斷言,而 假設斷言沒有 副作用,在正常條件下仍產生相同的 結果。在 異常情況下,禁用 聲明檢查可能意味着將會中止的 程序將繼續運行。這有時是 更好。 Wikipedia

所以,如果你的代碼的正確性依賴於斷言在那裏你可能會遇到嚴重問題。當然,如果代碼在測試過程中工作,它應該在生產過程中工作...現在輸入第二個代碼工作,並只是要解決一個小問題...

+0

我認爲問題在於運輸前決定不測試軟件的小問題。測試階段不能被明顯地「跳過」,因此斷言也不能。 – Galik 2017-09-11 09:07:55

3

我有些情況下,斷言時被禁用建設發佈。你可能無法控制這個(否則,你可以用assert打開),所以這樣做可能是個好主意。

「糾正」輸入值的問題是調用者不會得到他們期望的結果,這會導致程序完全不同部分的問題甚至崩潰,使得調試成爲一場噩夢。

我通常在if語句拋出一個異常接管斷言的作用的情況下,它們將被禁止

assert(value>0); 
if(value<=0) throw new ArgumentOutOfRangeException("value"); 
//do stuff 
+2

我喜歡拋出異常:它總是起作用(生產和調試),但爲什麼然後會寫一個assert語句呢?這只是「時代的一半」。 – jan 2008-09-11 11:09:35

+0

我認爲這只是一個慣例問題。當我看到一個未捕獲的異常時,可能有數百萬事件造成了這種異常。當我發現一個失敗的斷言時,我知道我搞砸了自己,對我來說找到原因更容易。 – Rik 2008-09-13 15:47:44

1

如果我從CS級記錯

前提條件定義是什麼條件你的函數的輸出被定義。如果你使你的函數處理錯誤條件,你的函數被定義爲這些條件,你不需要assert語句。

所以我同意。通常你不需要兩個。

正如Rik評論說,如果您在已發佈的代碼中刪除斷言,可能會導致問題。通常我不會那樣做,除非在性能關鍵的地方。

+0

這種方法的問題在於,非法調用導致的崩潰可能發生在程序完全不同的部分,這使得調試成爲一場噩夢。 – Rik 2008-09-11 10:04:48

-1

斷言的一個問題是它們可以(通常會)編譯出代碼,所以你需要添加兩面牆以防被編譯器拋出。

1

不要忘記,大多數語言可以讓你關閉斷言...就個人而言,如果我準備寫測試,以防止所有範圍的無效輸入,我不會打擾在斷言第一個地方。

另一方面,如果您不編寫邏輯來處理所有情況(可能是因爲嘗試繼續無效輸入不明智),那麼我將使用斷言聲明併爲「提前失敗」做法。

0

對於內部功能,只有您會使用的功能,請僅使用聲明。斷言將有助於在測試過程中發現錯誤,但不會妨礙生產性能。

檢查來自外部的輸入if-conditions。從外部看,這就是你/你的團隊控制和測試的代碼之外的任何地方。

或者,您可以有均爲。這將是面向外部功能的集成測試將在生產之前完成的功能。

2

我不同意這種說法:

只有在調用者知道什麼是「有效的 輸入值」是你的函數,並 他必須檢查它的有效性,他 調用你的函數之前。

來電可能認爲他知道輸入值是正確的。只有方法作者知道它是如何工作的。程序員的最佳目標是讓客戶陷入「pit of success」。在特定情況下,您應該決定哪種行爲更合適。在某些情況下,不正確的輸入值可以原諒,在其他情況下,您應該拋出異常\返回錯誤。

至於Asserts,我會重複其他評論者,斷言是調試時間檢查代碼作者,而不是代碼客戶端。

0

我應該說我意識到在生產代碼中聲明(這裏)消失的事實。

如果if語句實際上糾正了生產代碼中的無效輸入數據,這意味着斷言在測試調試代碼期間從未關閉,這意味着您編寫了從未執行過的代碼。

對我來說這是一個或情況:

(報價安德魯)「防止無效輸入的所有範圍,我不會擺在首位斷言打擾」 - >寫一個if-test。

(quote aku)「不正確的輸入值可以原諒」 - >寫一個斷言。

我不能代表驗證你控制輸入都...

4

使用斷言:私有方法和這樣的。

使用如果驗證輸入你不控制語句:公共接口由用戶設計的消費,用戶輸入測試等

測試你與內置的斷言應用程序隨後沒有斷言部署。