2017-06-05 40 views
1

我有一个函数验证一个模型类,它必须检查每个类的成员是非空或非空的字符串的情况下。如何测试具有N个不同路径的函数?

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成员变量的数量被检查,如何可靠地为所有可能的路径编写测试?

现在,我有两个简单的测试案例:

  1. 只有一些成员设置和检查assertFalse(is_complete(foo))
  2. 其中所有成员设置和检查​​

但我有一种感觉,这可能还不够。

+1

在单元测试中,您不一定要测试每条路径。有许多功能甚至不可能实用。你只是想测试足够。如果一个函数很复杂,这可能是一个标志,应该把它分解成更小的函数。 – ThomasW

+0

你应该认真反思你的课堂设计。理想情况下,应该不可能首先创建部分初始化对象。施工人员应该照顾这一点。如果您在建造时无法获得初始化班级所需的某些数据,请尝试将其提取到不同的班级中。 –

+0

@FrankPuffer将它的成员作为空字符串或空值的实例不会被视为初始化_部分,因为它代表实例可以处于的有效状态。它可能表示用户愿意将其留空的某些字段的表单。 –

回答

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: 
+0

你是对的。这只是'n'路径。对不起,我会改正标题。 –

1

你可以用随机测试:

  • 编写一个函数,创建一个包含所有字段的随机Profile对象(可以是随机的,但是有效的)。
  • 随机地将一个或多个字段更改为无或空
  • 将对象传递给is_complete()函数。

我只能用Qala Datagen在Java中展示这个。我假设你感兴趣的负路径,因此它可以是这样的:

@Test void profileIsNotComplete_ifAtLeastOneFieldIsBlank() { 
    Profile p = Profile.random(); 
    callOneOrMore(
     () -> profile.setName(nullOrEmpty()), 
     () -> profile.setLastName(nullOrEmpty()), 
     ...); 
    assertFalse(profile.isComplete(); 
} 

注意,这个代码的实际测试 - 它还会检查设置为空/空字段的组合。如果在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

相关问题