如何为测试具有多个参数的方法命名和组织单元测试?

7

给定需要测试的方法:

// Search the given value using the provided search options
// Return true if the searchValue was found; false otherwise 
bool Search(string searchValue, bool useExactSearch, bool useIndexing)

我有六个重要的搜索值(其中一个包含标点符号,另一个包含重音字符,另一个包含换行符等),我需要使用每种可能的useExactSearch和useIndexing组合来验证这些值。这意味着有54个测试用例。

你该怎么做呢?你真的会写54个单元测试吗?如果是这样,你会如何命名它们?你是否只为最重要的情况编写测试?你是否编写一个单独的单元测试,循环遍历参数值和预期结果的表格?如果我只编写一个单元测试,当持续集成报告失败时,更难找到哪个测试用例出了问题。

4个回答

5
如果您正在使用NUnit (.Net),您可以这样做:
[TestCase("John*",true, false, false)]
[TestCase("*user*",false, true, true)]
[TestCase(".",true, false, true)]
public void SearchTest(string param1, bool param2, bool param3, bool expectedResult)
{
    YourClass clazz = new YourClass();
    bool result = clazz.Search(param1, param2, param3);
    Assert.AreEqual(expectedResult, result);
}

NUnit测试运行器将执行此操作3次。正如您可以在此处看到的那样,报告显示所有的测试用例被分开,这有助于您识别是谁破坏了构建。

这个功能可能在大多数xUnit框架上都可用。


3
在他的书《单元测试的艺术》中,Roy Osherove建议使用以下命名约定:
MethodUnderTest_ConditionUnderTest_ExpectedBehaviour()

这个看起来很合理。至于如何使用不同参数对同一函数进行多次测试,我认为单独的测试将更清楚地说明出现了什么问题,并且您可以使用重构技术来最小化测试之间的重复。

顺便提一下,虽然这不是与语言无关的,但 NUnit 允许参数化测试,因此其他单元测试框架也可能会这样做。这是一个很好的折中方案,既避免了“一个难以理解失败原因”的单个测试,又避免了“几乎相同,有大量重复”的 54 个测试。


我对那个规则并不印象深刻。如果我们可以测试它,那么它必须是确定性的。这意味着预期行为完全由被测试的方法和测试条件决定,因此名称的第三部分是多余的。其次,如果您的设计发生了变化,预期行为可能会改变,但您仍然可能希望针对该条件测试该方法。 - Raedwald
1
@Raedwald:是的,它应该是完全确定性的,但如果你回到一年前写的测试,有一个解释对于你期望的结果来说是很好的。至于你的第二个观点,如果期望的行为发生变化,测试逻辑也会改变,所以在那时你可以重命名它。 - Jackson Pope
1
在断言消息中详细说明你期望的内容,这样做很好。 - Raedwald
1
通常我也使用“三部分命名风格”,例如我喜欢一个名为Seach_WhenSearchingPartialWordsWithIndexingTurnedOn_NoResultsAreFound的测试。但是当你有54个用例针对单个方法时,测试名称变得相当长且难以理解。 - Sylvain
2
@Raedwald:是的,这在断言消息中,但将其放入方法名称中的一个好理由是,您可以从测试运行器摘要中快速了解失败的原因。 - User
显示剩余2条评论

0
一个人应该至少为重要的测试用例编写测试,并且测试可以根据测试用例命名,例如TestSeachForPunctuation、TestSeachForAccentedChars、TestSeachForLineBreaks。

0
有时将参数化测试拆分为正面和负面情况,可以更好地命名测试方法名称中的“ConditionUnderTest”和“ExpectedBehaviour”部分,如果您使用模式MethodUnderTest_ConditionUnderTest_ExpectedBehaviour()
请参见https://freecontent.manning.com/making-better-unit-tests/上给出的示例。

作为一种妥协,您可以将正面测试用例提取到自己的测试中,并从描述性命名中受益,这在确定有效和无效交货日期的区别方面最为重要(清单12)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接