腾讯优测分享正反思维对软件测试的认知
什么是软件测试?人们常常回答:软件测试就是发现软件产品中的bug(缺陷)。也有人说,不对,软件测试是验证软件产品特性是否满足用户的需求。实际上,上述回答都没错,是对软件测试的正反两个方面的解释。
早期,人们更多的是将“测试”看作是对产品的“检验”,检查软件的每个功能是否运行正常。正如1983年Bill Hetzel将软件测试定义为:“软件测试就是一系列活动,这些活动是为了评估一个程序或软件系统的特性或能力,并确定其是否达到了预期结果。”从这个定义中,至少我们可以看到以下两点。
测试试图验证软件是“工作的”,也就是验证软件功能执行的正确性。
测试的活动是以人们的“设想”或“预期的结果”为依据。这里的“设想”或“预期的结果”是指需求定义、软件设计的结果。
但同时我们知道,软件测试有一条原则:**测试是不能穷尽的。测试会面对大量的测试数据、测试场景或代码路径等,测试也只是一个样本实验,不能证明软件是正确的,只能说明发现的缺陷的确是缺陷。**但如果没有发现问题,并不能说明问题就不存在,而是至今未发现软件中所潜在的问题。正如《软件测试的艺术》一书作者Glenford J. Myers所说,测试不应该着眼于验证软件是工作的,相反,应该用逆向思维去发现尽可能多的错误。他认为,**从心理学的角度看,如果将 “验证软件是工作的”作为测试的目的,非常不利于测试人员发现软件的错误。**因此,1979年他给出了软件测试的不同的定义:“测试是为了发现错误而执行一个程序或者系统的过程。”从这个定义可以看出,假定软件总是存在缺陷的(事实上也是如此)、有错误的,测试就是为了发现缺陷,而不是证明程序无错误。
从这个定义延伸出去,一个成功的测试是发现了软件问题的测试,否则测试就没有价值。这就如同一个病人(因为是病人,假定确实有病),到医院去做相应的检查,结果没有发现问题,那说明这次体检是失败的,浪费了病人的时间和金钱。以逆向思维方式引导人们证明软件是“不工作的”,会促进我们不断思考开发人员对需求理解的误区、不良的习惯、程序代码的边界、无效数据的输入等,找到系统的薄弱环节或识别出系统复杂的区域,目标就是发现系统中各种各样的问题。
**人类的活动具有高度的目的性,建立适当的目标具有显著的心理作用。**如果测试目的是为了证明程序里面没有错误,潜意识里就可能不自觉地朝这个方向去做。在进行测试的过程中,就不会刻意选择一些尽量使程序出错的测试数据,而选择一些常用的数据,测试容易通过,而不容易发现问题。如果测试的目的是要证明程序中有错,那我们会设法选择一些易于发现程序错误的测试数据,这样,更早、更快地发现缺陷。毕竟开发人员力求构造软件,以正向思维方式为主,所以逆向思维方式可以提升我们的测试效率。
**逆向思维也有不利的一面,容易陷于局部的深度测试,缺乏广度。**因为觉得某个地方有缺陷,就对这个地方进行测试,然后不断深入下去,这样容易忽视一些区域。虽然那些地方产生的缺陷不多,但如果产生了严重缺陷,也是我们不能承受的。所以正向思维也是有价值的,它会督促针对软件系统的所有功能点,逐个验证其正确性,哪个功能越重要越要进行检验。正向思维会让我们的测试更有广度——良好的测试覆盖面。
**为了做好测试,既要有深度,又要有广度;既要,又要有测试工作自身完整的质量。所以,我们应该将正向思维和逆向思维有机地结合起来,做到效率和质量的平衡。换句话说,当我们需要效率时,更多采用逆向思维,当我们需要测试广度来确保完整的测试质量时,则多采用正向思维。**这种平衡还体现在不同的应用领域,例如国防、航天、银行等关键性软件系统,承受不了系统的任何一次失效。因为这些失效完全有可能导致灾难性的事件,所以强调验证(verify),以保证非常高的软件质量。而一般的商业应用软件或服务,质量目标设置在“用户可接受水平”,以降低软件开发成本,加快软件发布速度,有利于市场的扩张,则可以强调逆向思维,尽快找出大部分缺陷。
早期,人们更多的是将“测试”看作是对产品的“检验”,检查软件的每个功能是否运行正常。正如1983年Bill Hetzel将软件测试定义为:“软件测试就是一系列活动,这些活动是为了评估一个程序或软件系统的特性或能力,并确定其是否达到了预期结果。”从这个定义中,至少我们可以看到以下两点。
测试试图验证软件是“工作的”,也就是验证软件功能执行的正确性。
测试的活动是以人们的“设想”或“预期的结果”为依据。这里的“设想”或“预期的结果”是指需求定义、软件设计的结果。
但同时我们知道,软件测试有一条原则:**测试是不能穷尽的。测试会面对大量的测试数据、测试场景或代码路径等,测试也只是一个样本实验,不能证明软件是正确的,只能说明发现的缺陷的确是缺陷。**但如果没有发现问题,并不能说明问题就不存在,而是至今未发现软件中所潜在的问题。正如《软件测试的艺术》一书作者Glenford J. Myers所说,测试不应该着眼于验证软件是工作的,相反,应该用逆向思维去发现尽可能多的错误。他认为,**从心理学的角度看,如果将 “验证软件是工作的”作为测试的目的,非常不利于测试人员发现软件的错误。**因此,1979年他给出了软件测试的不同的定义:“测试是为了发现错误而执行一个程序或者系统的过程。”从这个定义可以看出,假定软件总是存在缺陷的(事实上也是如此)、有错误的,测试就是为了发现缺陷,而不是证明程序无错误。
从这个定义延伸出去,一个成功的测试是发现了软件问题的测试,否则测试就没有价值。这就如同一个病人(因为是病人,假定确实有病),到医院去做相应的检查,结果没有发现问题,那说明这次体检是失败的,浪费了病人的时间和金钱。以逆向思维方式引导人们证明软件是“不工作的”,会促进我们不断思考开发人员对需求理解的误区、不良的习惯、程序代码的边界、无效数据的输入等,找到系统的薄弱环节或识别出系统复杂的区域,目标就是发现系统中各种各样的问题。
**人类的活动具有高度的目的性,建立适当的目标具有显著的心理作用。**如果测试目的是为了证明程序里面没有错误,潜意识里就可能不自觉地朝这个方向去做。在进行测试的过程中,就不会刻意选择一些尽量使程序出错的测试数据,而选择一些常用的数据,测试容易通过,而不容易发现问题。如果测试的目的是要证明程序中有错,那我们会设法选择一些易于发现程序错误的测试数据,这样,更早、更快地发现缺陷。毕竟开发人员力求构造软件,以正向思维方式为主,所以逆向思维方式可以提升我们的测试效率。
**逆向思维也有不利的一面,容易陷于局部的深度测试,缺乏广度。**因为觉得某个地方有缺陷,就对这个地方进行测试,然后不断深入下去,这样容易忽视一些区域。虽然那些地方产生的缺陷不多,但如果产生了严重缺陷,也是我们不能承受的。所以正向思维也是有价值的,它会督促针对软件系统的所有功能点,逐个验证其正确性,哪个功能越重要越要进行检验。正向思维会让我们的测试更有广度——良好的测试覆盖面。
**为了做好测试,既要有深度,又要有广度;既要,又要有测试工作自身完整的质量。所以,我们应该将正向思维和逆向思维有机地结合起来,做到效率和质量的平衡。换句话说,当我们需要效率时,更多采用逆向思维,当我们需要测试广度来确保完整的测试质量时,则多采用正向思维。**这种平衡还体现在不同的应用领域,例如国防、航天、银行等关键性软件系统,承受不了系统的任何一次失效。因为这些失效完全有可能导致灾难性的事件,所以强调验证(verify),以保证非常高的软件质量。而一般的商业应用软件或服务,质量目标设置在“用户可接受水平”,以降低软件开发成本,加快软件发布速度,有利于市场的扩张,则可以强调逆向思维,尽快找出大部分缺陷。