我有一个“最佳实践”问题。我正在为某个方法编写测试,但有多个入口值。我应该为每个入口值编写一个测试,还是应该更改entryValues变量的值,并调用.assert()方法(对所有可能值的范围进行测试)?
谢谢你的帮助。 最好的问候,
Pedro Magueija
编辑:我正在使用.NET。Visual Studio 2010与VB。
谢谢你的帮助。 最好的问候,
Pedro Magueija
编辑:我正在使用.NET。Visual Studio 2010与VB。
如果你需要编写许多测试,这些测试仅在初始输入和最终输出方面有所不同,那么你应该使用数据驱动测试。这样可以一次定义测试以及输入和输出之间的映射关系。单元测试框架将把其解释为每个用例一个测试。如何实际操作取决于您使用的框架。
最好为您要测试的方法编写单独的单元测试,覆盖每个输入/输出集的所有可能值(或者至少是您想要进行单元测试的那些输入/输出集)。
因此,如果您有一个像以下这样的单个方法:
void testAll() {
// setup1
assert()
// setup2
assert()
// setup3
assert()
}
void testDivideByZero() {
// setup
assert()
}
void testUnderflow() {
// setup
assert()
}
void testOverflow() {
// setup
assert()
}
define add_one(num) {
return num+1;
}
我无法针对所有可能的值编写测试,因此我可能会使用MAX_NEGATIVE_INT、-1、0、1、MAX_POSITIVE_INT作为我的测试集,因为它们是我可能得到的有趣值的良好代表。
您应该至少有一个输入与每个代码路径相对应。如果您有一个函数,其中每个值都对应于唯一的代码路径,那么我会考虑为可能值的完整范围编写测试。这样做的一个例子是命令解析器。
define execute(directive) {
if (directive == 'quit') { exit; }
elsif (directive == 'help') { print help; }
elsif (directive == 'connect') { intialize_connection(); }
else { warn("unknown directive"); }
}
- (void) testSomething
{
[foo callBarWithValue:x];
assert…
}
- (void) testSomething2
{
[foo callBarWithValue:y];
assert…
}
对比。
- (void) testSomething
{
[foo callBarWithValue:x];
assert…
[foo callBarWithValue:y];
assert…
}
第一种版本更好,因为当测试失败时,您将更清楚地知道哪些部分不起作用。第二个版本显然更方便。有时我甚至会将测试值放入集合中以节省工作量。当我可能想要单独调试某个特定案例时,我通常选择第一种方法。当测试值确实属于同一组并形成一个连贯的单元时,我当然只选择后者。
你有两个选择,但你没有提到你使用的测试框架或语言,所以其中一个可能不适用。
1)如果你的测试框架支持它,请使用RowTest,MBUnit和Nunit支持这一点。如果你使用.NET,这将允许你在方法上放置多个属性,并且每行都将作为单独的测试执行。
2)如果不支持,则为每个条件编写一个测试,并确保给它一个有意义的名称,以便在测试失败时(当测试失败时)可以轻松找到问题并且对你有意义。
编辑 在Nunit中称为TestCase Nunit TestCase Explination