当单元测试时,边缘情况下测试相同的方法每个都需要单独的测试方法。例如,测试传递给以下函数的空字符串:
public function add($numbers)
{
$numbers = preg_replace('/\s/', '', $numbers);
if ($numbers === "") {
return 0;
}
}
我显然想要抓住边缘案例,例如:
""
" "
"\t \n"
"asd"
等
那么需要多少测试方法才能证明这种方法有效?
public function testAddEmptyString()
{
$stringCalculator = new StringCalculator();
$this->assertSame(0, $stringCalculator->add(""));
}
public function testAddEmptyStringWithSpaces()
{
$stringCalculator = new StringCalculator();
$this->assertSame(0, $stringCalculator->add(" "));
}
public function testAddEmptyStringWithCharacters()
{
$stringCalculator = new StringCalculator();
$this->assertSame(0, $stringCalculator->add("asd"));
}
这似乎是测试类将包含大量的方法,用于任何非平凡的
答案 0 :(得分:1)
在这个简单的情况下(一个实际的函数,即没有副作用,没有例外,每个测试用例基本上只有一行)我会说单个测试方法没问题。
如果您有更复杂的测试用例需要设置代码,那么每个测试用例都应该有自己的测试方法。
答案 1 :(得分:0)
这是一个意见问题,所以恕我直言,一种测试方法应该测试一个场景,总是。
话虽如此,并且考虑到您应该像生产代码一样对待您的测试代码,您应该努力进行简洁的设计 - 在这种情况下,DRY。
每种语言都有自己的方法来实现这一目标,但通常提取方法都可以解决问题。就其本身而言,如果它们是孤立的,明确的意图等,那么进行许多测试是没有害处的。
例如,xUnit(C#)解决此问题的方式如下所示:
[Theory]
[InlineData("")]
[InlineData(" ")]
[InlineData("\t \n")]
[InlineData("asd")]
public void Add_NonNumber_ZeroReturned(string numbers)
{
var underTest = new UnderTest();
var result = underTest.Add(numbers);
Assert.Equal(0, result);
}
答案 2 :(得分:0)
你应该有很多单独的测试方法,不要担心它们中有多少。
尝试将多个测试塞入方法中的坏处是,当测试失败时,您不知道破坏的真实程度,因为测试的一部分失败会阻止测试的其余部分运行。 当您看到测试中断并进行修复时,结果可能会出现更多失败。
如果您组织测试以便在不同的测试中处理不同的案例,那么您将立即看到所有失败。
如果所有边缘情况都是传入不同数据的实例,并且它们都以相同的方式调用,您可能需要检查测试框架是否支持参数化测试。
答案 3 :(得分:0)
您应该将所有这些边缘案例值的数组与测试分开。
String[] edgeCaseValues = {""," ","\t \n","asd"};
然后在测试中你可以简单地遍历它们将它们传递给你的函数
foreach(var edgeCaseValue in edgeCaseValues)
{
$stringCalculator = new StringCalculator();
$this->assertSame(0, $stringCalculator->add(edgeCaseValue));
}
这样您就可以在其他测试中重复使用它们,如果添加新的边缘案例值,它们将全部添加到所有测试中