共用方式為


使用動態符號執行產生輸入

IntelliTest 會藉由分析程式中的分支條件來產生 參數化單元測試 的輸入。 測試輸入是根據它們是否可以觸發程式的新分支行為來選擇的。 分析是一個漸進式過程。 它會精簡述詞q: I -> {true, false},針對形式測試輸入參數Iq 代表 IntelliTest 已觀察到的一組行為。 最初, q := false因為尚未觀察到任何東西。

循環的步驟是:

  1. IntelliTest 會判斷輸入 i ,以便 q(i)=false 使用 條件約束求解器。 通過構建,輸入 i 將採用以前從未見過的執行路徑。 最初,這意味著 i 可以是任何輸入,因為尚未找到任何執行路徑。

  2. IntelliTest 會使用所選輸入 i執行測試,並監視測試和受測程式的執行。

  3. 在執行過程中,程式會採用由程式的所有條件分支決定的特定路徑。 決定執行的所有條件集合稱為路徑條件,表示為對形式輸入參數的述詞p: I -> {true, false} 。 IntelliTest 會計算此述詞的表示法。

  4. IntelliTest 集 q := (q or p)。 換句話說,它記錄了它已經看到了 所 p代表的路徑的事實。

  5. 前往步驟 1。

IntelliTest 的 條件約束求解器 可以處理 .NET 程式中可能出現的所有類型的值:

IntelliTest 會篩選出違反陳述假設的輸入。

除了立即輸入 ( 參數化單元測試的引數) 之外,測試還可以從 PexChoose 靜態類別繪製更多輸入值。 這些選擇也會決定 參數化模擬的行為。

約束求解器

IntelliTest 會使用條件約束求解器來判斷測試和受測程式的相關輸入值。

IntelliTest 使用 Z3 條件約束求解器。

動態程式碼涵蓋範圍

作為執行階段監視的副作用,IntelliTest 會收集動態程式代碼涵蓋範圍資料。 這稱為 動態 ,因為 IntelliTest 只知道已執行的程式碼,因此它無法像其他涵蓋面工具通常一樣提供涵蓋範圍的絕對值。

例如,當 IntelliTest 將動態涵蓋面報告為 5/10 基本區塊時,這表示涵蓋了 10 個區塊中的 5 個區塊,其中分析到目前為止已達到的所有方法中的區塊總數 (與測試元件中存在的所有方法相反) 為 10 個。 在分析的後期,隨著發現更多可行的方法,分子(在本例中為 5)和分母(10)都可能增加。

整數和浮點數

IntelliTest 的 條件約束求解器 會判斷基本類型 ( 例如 byteintfloat 等) 的測試輸入值,以觸發測試和受測程式的不同執行路徑。

物件

IntelliTest 可以 建立現有 .NET 類別的實例,也可以使用 IntelliTest 自動 建立模擬物件 ,以實作特定介面,並視使用方式以不同的方式運作。

具現化現有類別

問題出在哪裡?

IntelliTest 會在執行測試和受測程式時監視已執行的指令。 特別是,它會監控對欄位數據的所有存取。 然後,它使用 約束求解器 來確定新的測試輸入,包括物件及其欄位值,以便測試和被測程式將以其他有趣的方式運作。

這表示 IntelliTest 必須建立特定類型的物件,並設定其欄位值。 如果類別是 可見 的,而且具有 可見 的預設建構函式,IntelliTest 可以建立類別的實例。 如果類別的所有欄位都 可見,IntelliTest 可以自動設定欄位。

如果類型不可見,或欄位不 可見,IntelliTest 需要協助來建立物件,並將其帶入有趣的狀態,以達到最大的程式碼涵蓋範圍。 IntelliTest 可以使用反映以任意方式建立和初始化實例,但這通常不是理想的選擇,因為它可能會將物件帶入在正常程式執行期間永遠不會發生的狀態。 相反地,IntelliTest 依賴使用者的提示。

可見度

.NET 有一個精心設計的可見性模型:類型、方法、欄位和其他成員可以是 私有公用內部等等。

當 IntelliTest 產生測試時,它只會嘗試從產生的測試內容中執行與 .NET 可見度規則相關的動作 (例如呼叫建構函式、方法和設定欄位)。

規則如下所示:

  • 內部成員的可見性

    • IntelliTest 假設產生的測試將可以存取所有在封閉 PexClass 中可見的內部成員。 .NET 具有 InternalsVisibleToAttribute ,可將內部成員的可見度延伸至其他元件。
  • PexClass 的私人和家庭 (在 C# 中受保護) 成員的可見度

    • IntelliTest 一律會將產生的測試直接放在 PexClass 中或子類別中。 因此,IntelliTest 假設它可以使用所有可見的家族成員 (在 C# 中受保護 ) 。
    • 如果產生的測試直接放入 PexClass 中 (通常是使用部分類別) ,IntelliTest 會假設它也可能使用 PexClass 的所有私人成員。
  • 公開成員的可見性

    • IntelliTest 假設它可以使用 PexClass 內容中可見的所有匯出成員。

參數化模擬

如何測試具有介面類型參數的方法? 還是屬於非密封類? IntelliTest 不知道呼叫這個方法時稍後會使用哪些實作。 也許在測試時甚至沒有可用的實際實現。

傳統的答案是使用具有明確行為的 模擬物件

模擬物件會實作介面 (或擴充非密封類別) 。 它並不代表真正的實現,而只是一個允許使用模擬物件執行測試的捷徑。 在每個使用它的測試案例中,其行為是手動定義的一部分。 有許多工具可以輕鬆定義模擬物件及其預期行為,但此行為仍必須手動定義。

與在模擬物件中使用硬式編碼的值不同,IntelliTest 可以產生這些值。 就像它啟用 參數化單元測試一樣,IntelliTest 也啟用參數化模擬。

參數化模擬有兩種不同的執行模式:

  • 選擇:探索程式碼時,參數化模擬是其他測試輸入的來源,而 IntelliTest 會嘗試選擇有趣的值
  • 重播:執行先前產生的測試時,參數化的模擬會像預先定義行為的存根一樣運作。

使用 PexChoose 取得參數化模擬的值。

結構體

IntelliTest 對 結構 值的推理類似於它處理 物件的方式。

陣列和字串

IntelliTest 會在執行測試和受測程式時監視已執行的指令。 特別是,它觀察程式何時依賴於字串或數組的長度(以及多維數組的下限和長度)。 它還觀察程式如何使用字串或數組的不同元素。 然後,它使用 約束求解器 來確定哪些長度和元素值可能會導致測試和被測程式以有趣的方式運作。

IntelliTest 會嘗試將觸發有趣程式行為所需的陣列和字串大小降到最低。

取得其他輸入

PexChoose 靜態類別可用來取得測試的其他輸入,並可用來實作參數化模擬

有意見反應嗎?

開發人員社群上張貼您的想法和功能要求。