單元測試中可以有循環嗎?單元測試中的循環
我的方法返回一個IEnumerable<IEnumerable>
,我想單元測試這個邏輯IEnumerable<IEnumerable>
創建。基本上我想測試IEnumerable
中元素的計數是否與預期一致。
我找不到一個替代方法來測試內部IEnumerable
沒有循環語句。請讓我知道這是不是一個好習慣。
單元測試中可以有循環嗎?單元測試中的循環
我的方法返回一個IEnumerable<IEnumerable>
,我想單元測試這個邏輯IEnumerable<IEnumerable>
創建。基本上我想測試IEnumerable
中元素的計數是否與預期一致。
我找不到一個替代方法來測試內部IEnumerable
沒有循環語句。請讓我知道這是不是一個好習慣。
沒有技術上的原因,你不能這樣做。您可以在單元測試中使用多個Assert語句。在循環中使用Assert語句只是在測試中使用多個Assert語句的簡便方法。
但是,有些人認爲在單元測試中應該只有一個Assert語句。
我個人不同意 - 我認爲一個測試應該測試單一的東西 - 爲了做到這一點,有時您可能需要多個Assert語句。
如果你的方法返回商品的IEnumerable,每個產品包含Color的的IEnumerable,那麼我認爲下面的測試是爲罰款:
[Test]
public void All_products_should_have_some_colors()
{
var products = GetProducts();
foreach (var product in products)
{
Assert.IsNotEmpty(product.Colors);
}
}
但是,你需要注意的是,如果IEnumerable包含0個元素,循環將永遠不會執行任何Assert語句,並且您的單元測試將「通過」 - 而您可能會讓它失敗。
糾正這種情況,你可以有一個單獨的測試確保有在了IEnumerable大於0的元素(即的GetProducts並實際上將返回一些產品的):
Assert.IsNotEmpty(products);
一個原因,以避免書寫測試中的一個循環就是讓測試一目瞭然,簡潔易讀。由於您使用NUnit標記了問題,並且您說您只是想測試元素數量是否與預期的一樣,請考慮使用NUnit Constraints進行聲明。
例如,
IEnumerable<IEnumerable<char>> someStrings = new[] { "abc", "cat", "bit", "hat" };
Assert.That(someStrings, Has.All.With.Length.EqualTo(3).And.All.Contains("a"));
失敗消息:
預期:至3的所有項目屬性長度相等且含有 「一」 所有項目字符串,但是:< 「ABC」, 「貓」,「位」,「帽子」>
但通過如果您更改「位」爲「蝙蝠」。
這本書的xUnit測試模式:重構測試代碼 傑拉德梅薩羅斯
有許多問題的答案,如你的。
+1,用於暗示使用NUnit約束,但是我建議您可能想要將長度和「包含」約束拆分爲單獨的測試或至少單獨的斷言。 – 2017-08-10 17:40:52
是的,你可以在單元測試中有循環,但要謹慎。如Alex York所述,如果您測試一個的東西,循環是可以接受的;即一個期望。
如果你使用的循環,那麼我建議你必須做兩件事情:
這是我測試一個對象的大於屬性的例子。
[Test]
public void TestCompare_XtoY_GreaterThan()
{
int numObjects = mOrderedList.Count;
for (int i = 1; i < numObjects; ++i)
{
for (int j = 0; j < i; ++j)
{
string testDescription = string.Format("{0} is greater than {1} which implies\n {2}\n is greater than\n {3}"
, i, j
, mOrderedList[i], mOrderedList[j]
);
Assert.IsTrue(0 < mOrderedList[i].CompareTo(mOrderedList[j]), testDescription);
Assert.IsTrue(0 < mOrderedList[i].Compare(mOrderedList[i], mOrderedList[j]), testDescription);
Assert.IsTrue(0 < mOrderedList[j].Compare(mOrderedList[i], mOrderedList[j]), testDescription);
Assert.Greater(mOrderedList[i], mOrderedList[j], testDescription);
}
}
}
我測試我的有序列表使用的測試設置非空:
[SetUp]
public void GeneralTestSetup()
{
// verify the iterated sources are not empty
string testDescription = string.Format("The ordered list of objects must have at least 3 elements, but instead has only {0}.", mOrderedList.Count);
Assert.IsTrue(2 < mOrderedList.Count, testDescription);
}
我有多個斷言,即使在我的循環,但所有的斷言測試的單一預期:
if i > j then mOrderedList[i] > mOrderedList[j]
在迭代級別的測試說明是等你拿故障,如:
10 is greater than 9 which implies
TestActionMethodInfo: [Actions.File, Version=1.0.446.0, File, VerifyReadOnly]
is greater than
TestActionMethodInfo: [Actions.File, Version=1.0.446.0, File, Write]
Expected: True
But was: False
,而不只是:
Expected: True
But was: False
約我上面的代碼問題/爭論:
是我在測試一個東西嗎?
我對對象內的4種不同比較方法斷言,這可能會被認爲是測試4件事情之一。計數器大於大於大於,並且所有進行評估的方法應該一致。
感謝您的回覆。術語「可接受的」意味着以敏捷的方式做到這一點是否是一種好的做法。 – Shankar 2011-05-01 10:02:57
我認爲我的答案中的測試是「可以接受的」,原因如下:1)測試「單一事物」(所有產品都有一些顏色)。 2)它簡單易讀。 – 2011-05-01 10:04:36
好吧..那就是我所需要的。我問這個問題是因爲有人說我們在每個測試中只需要一個Assert,所以我想從他們那裏知道我們如何去測試這個方法:) – Shankar 2011-05-01 10:06:46