我有一个验证模型类的函数,它必须在类的情况下检查类的每个成员是非空的还是非空的。
这个is_complete
函数的逻辑是这样的:
def is_complete(profile):
if profile.first_name in (None, ''):
return False
elif profile.last_name in (None, ''):
return False
elif profile.dob is None:
return False
.
.
.# and checks so on for all members of the profile instance
.
.
return True
我的问题,因为执行可能采用的路径数量非常大,并且与要检查的profile
成员变量的数量成比例增加,如何可靠地为所有可能路径编写测试?
现在,我有两个简单的测试用例:
assertFalse(is_complete(foo))
assertTrue(is_complete(foo))
但我觉得这可能还不够。
答案 0 :(得分:1)
我不确定拥有MxN
路径的含义。在发布的代码中,您拥有与字段+ 1一样多的路径。
创建一个帮助方法,创建一个完整的profile
并传递is_complete
。
为完整的is_complete(profile)
添加一个测试方法,以验证True
为profile
。
为每个字段添加一个测试方法,步骤如下:
is_complete
is_complete
返回False
您将拥有与字段+ 1一样多的测试方法。
顺便说一下,而不是这个:
if profile.first_name in (None, ''):
你可以更简单地写作:
if not profile.first_name:
答案 1 :(得分:1)
您可以使用随机化进行测试:
我只能在Qala Datagen的Java中显示这一点。我假设你对负面路径感兴趣,所以看起来像这样:
@Test void profileIsNotComplete_ifAtLeastOneFieldIsBlank() {
Profile p = Profile.random();
callOneOrMore(
() -> profile.setName(nullOrEmpty()),
() -> profile.setLastName(nullOrEmpty()),
...);
assertFalse(profile.isComplete();
}
注意,此代码实际上测试更多 - 它还检查设置为null / empty的字段组合。如果在Python中没有这样的库,你可以为自己编写一些实用程序方法。
NB :每次执行只会测试一条路径。你可以运行它多次(一千?),以确保所有路径都通过。然后在CI中,如果这不是关键任务功能,您只能运行一次,并且您不会担心它会经常中断。
否则,如果您真的希望每次调用 100%覆盖,您可以违反一些良好做法并将所有这些测试合并为一个(否则将会有太多使阅读变得复杂的测试):
@Test void profileIsNotComplete_ifOneFieldIsBlank() {
assertFalse(Profile.random().setName(null).isComplete());
assertFalse(Profile.random().setName("").isComplete());
assertFalse(Profile.random().setLastName(null).isComplete());
assertFalse(Profile.random().setLastName("").isComplete());
...
}
虽然这并没有测试组合,但您可以将这两种方法结合起来。在两种方法中,积极的情况都很容易:
@Test void profileIsComplete_ifAllFieldsAreFilled() {
assertTrue(Profile.random());
}
有关随机化测试的更多信息是here。