如果被測方法的預期結果存在於方法的官方文檔中,那麼在測試名稱中指示預期結果將是多餘的。事實上,如果目的是記錄方法,那麼應該將文檔寫入方法的XML文檔中,這將提供Intellisense信息等。C#單元測試:爲什麼必須將預期結果包含在測試名稱中?
爲什麼除了被測試方法之外的任何東西真的被包含在測試名稱中?
如果被測方法的預期結果存在於方法的官方文檔中,那麼在測試名稱中指示預期結果將是多餘的。事實上,如果目的是記錄方法,那麼應該將文檔寫入方法的XML文檔中,這將提供Intellisense信息等。C#單元測試:爲什麼必須將預期結果包含在測試名稱中?
爲什麼除了被測試方法之外的任何東西真的被包含在測試名稱中?
這是一個理解會議和發展實踐的問題。如果您正在使用TDD實施,那麼在測試名稱中記錄預期結果可以讓您專注於自己的目標。由於您尚未實現該類,因此也沒有XML文檔來指定預期的結果。 (您首先要編寫測試。)此處的額外好處是,記錄測試中的預期結果意味着您可以執行規範(又名測試)並驗證其是否正確。您無法執行XML文檔。 :)(您必須確保測試名稱和測試代碼相匹配,但這比確保其他文件中的測試代碼和XML文檔匹配更容易。)
除此之外,還有一些工具可以提取類/方法名稱並在HTML中爲您生成規範文檔。這使您可以輕鬆生成可供所有利益相關方審查的報告。您需要爲高級別測試/規格執行此操作,例如「在結帳時應用10%單項優惠代碼時,購物車中最昂貴的商品會打折10%。」這使得利益相關者可以驗證(因爲規範正在執行/傳遞)系統實現了某些與業務相關的功能。
那麼它沒有,但如果你說有10+測試試圖對同一方法不同的方案,並沒有把儘可能描述可能得到是一個真正的麻煩在看他們的時候。
在測試列表編輯器,你得到的測試的名字,這一切。在我的項目中,我們目前有600多個測試,因此瞭解哪種方法在運行時確實非常重要,並且您想嘗試某種特定方案。
我一直認爲,如果犯規滿足烏爾需要的東西不使用它/縫補滿足您的需求。我能想到的唯一合乎邏輯的解釋是,在你運行測試方法之後,你可以輸出合格/不合格記錄並將其交給經理,以便他們可以對他們的臉上有微笑,因爲我不知道他們爲什麼這麼認真: )......笑話分開了...... BDD緩慢而穩定地獲得勢頭的另一個原因。
真的你能說出任何你想要你的測試方法,他們只是方法。選擇適合你/你的團隊的命名約定。
然而,大多數測試運行不顯示XML文檔,只有方法名。如果方法名稱具有足夠的描述性,則不需要檢查測試代碼就可以瞭解導致測試失敗的事件(或未發生)。
試驗名稱應當包括被測試的方法和變體被測試。通常情況下,你應該比被測試的方法有更多的測試。你想至少對所有的邊界條件測試,不同的分支,等
MyMethod_Zero()
MyMethod_MinValue()
MyMethod_MaxValue()
MyMethod_SomeBranchTest()
等
因爲PoppingEmptyStackThrowsInvalidOperationException()
是更容易在測試運行時尋找比StackPopTest_1()
我不知道,我不喜歡最常見的命名約定。我發現他們很難閱讀和理解。基於其他一些命名約定(這我不能告訴現在是哪一個)我開發我自己的,那就是:
比方說,我有下面的類測試:
public class ColorParser {
public static bool TryParseHex(string value, out Color color) {
// Code to parse the hex color value.
}
}
我的單元測試此特定的方法如下所示:
public class ColorParserTests
{
public class TryParseHexTests
{
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void TestNullValue()
{
Color color = Color.Empty;
ColorParser.TryParseHex(null, out color);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void TestEmptyValue()
{
Color color = Color.Empty;
ColorParser.TryParseHex(string.Empty, out color);
}
[TestMethod]
public void TestInvalidValues()
{
string[] invalidValues = new string[]
{
"#",
"FF",
"#FF",
"#FFAA",
"asdf"
};
foreach (var invalidValue in invalidValues)
{
Color color = Color.Empty;
bool result = ColorParser.TryParseHex(invalidValue, out color);
Assert.IsFalse(result, string.Format("Value '{0}' must not pass the test!", invalidValue));
}
}
[TestMethod]
public void TestValidValues()
{
// Spaces are intended and a part of the test!
Dictionary<string, Color> validValues = new Dictionary<string, Color>()
{
{" #000000", Color.FromArgb(0,0,0)},
{" #010203 ", Color.FromArgb(1,2,3)},
{"#00FFFF", Color.FromArgb(0,255,255)},
{"#FF00FFFF", Color.FromArgb(255,0,255,255)},
};
foreach (var validValue in validValues)
{
Color color = Color.Empty;
bool result = ColorParser.TryParseHex(validValue.Key, out color);
Assert.IsTrue(result, string.Format("Value '{0}' must pass the test!", validValue.Key));
Assert.AreEqual(validValue.Value, color, "Parsed color must be the same.");
}
}
}
}
這背後的想法是,particualr測試分組(在類中),它允許我分別測試它們。無需重複每次測試的方法名稱。測試方法開始於一個動詞,如方法名稱應該和它只包含關於什麼exacly正在測試的簡短信息。其他一切都在測試中。
這樣我很快就知道我測試了什麼,結果應該在測試本身內部定義,因爲我測試的是某些值的行爲,無論是正確還是錯誤。
Nulls和Emptys以及其他引發異常的特殊情況值得他們自己進行測試。
你可以打破了測試,並寫更多的測試,如TestValuesWithSpaces
或TestNegativeDeposit
或TestUserNameWithInvalidCharacters
等,這總是取決於多少測試有和你想要做的是如何精確。在這種情況下,我認爲這是足夠的。無論如何,我認爲這是非常具有描述性的。