java 区分缺陷Defects/感染Infections/失败Failure
缺陷Defects
软件故障总是从代码中一个或多个缺陷的执行开始。
缺陷只是一段有缺陷、不正确的代码。
缺陷可能是程序语句的一部分或完整部分,也可能对应于不存在但应该存在的语句。
尽管程序员要对代码中的缺陷负责,但从技术上讲,他们可能并不总是有错——例如,问题可能是由一组规定不周的需求引起的。
传染Infections
感染是指执行缺陷时发生的情况,并且程序的状态受到影响。
当程序的状态被感染时,它开始不正确地工作:
•变量开始采用错误的值
•程序中做出的决策评估不正确,执行路径偏离正确路径。
但在这一点上,它并没有影响程序的输出(到目前为止,故障还没有明显的影响)。
故障Failure
当感染传播到程序
也就是说,程序明显地表现不正确。
软件故障是如何发生的?
Method:
此方法包含一个错误。或者更准确地说,是一个缺陷。
缺陷示例为第二个循环初始化程序。它应该使用i+1而不是i本身来迭代
这部分也是一种感染,让它过早地开始迭代字符串中的索引。这进一步导致字符串中的每个字符都被添加到重复集。但在这一点上,该程序没有明显的错误
因此,失败取决于程序何时交付可观察的输出。在本例中,我们在测试中询问方法的返回值,从而导致测试失败
但在整个软件的执行过程中,该方法可能会被另一种方法在内部使用,并且故障可能会在很久以后发生在不同的地方。
Tests:
第一测试通过,而第二测试失败。
Failures vs Test Failures
因此,我们需要区分故障和测试故障。
故障是指软件在生产中作为一个整体运行时表现不正确。
测试失败是指测试本身失败,原因是:
(a) 测试显示软件出现故障
(b) 测试本身是不正确的,例如,它对软件的行为做出了不正确的断言。
Testing vs Debugging
我们现在也可以揭穿测试和调试是相同的想法。
测试是通过观察软件的执行情况来评估软件的过程。
调试是将故障/测试故障追溯到最终导致故障的缺陷的过程。
软件故障是如何发生的?
1.包含缺陷的程序位置是在执行过程中达到。(Defect)
2.缺陷影响程序的状态 (Infection)
3.感染传播到程序的输出,导致失败。(Failure)
examples:
(1) 海平运行他的Python程序,根据学生一年级的模块成绩预测他们的最终学位分类。它产生了几行输出,但随后崩溃并出现错误。
故障
(2) Siobhan正在编写一个Java方法忘记将对象分配给引用,这意味着它为NULL。
缺陷
(3) 拉姆齐正在编写一个计算学生分数的程序。一个功能是找到最适合他的作业的学生。他的程序错误地从位置1而不是0开始迭代他的标记数组。但是位置0对应的是一个贫困学生,所以该程序仍然返回了正确的答案。
感染
(4) Emma正在测试她的RubyonRails应用程序。全部的测试通过了,但后来发现她误解了客户的一个要求。
缺陷/感染/失败,取决于情况
Defects are not always reached (executed)
for(int j = i; j < s.length(); j++)
如果输入字符串s为空,则满足条件
一个好的测试套件需要尽可能多地使用软件。
Defects may not always cause infections
for(int i = 0; i > s.length(); j++)
对于空字符串,缺陷将被执行,但没有变量采用错误的值和循环;loop body并没有被处死——这是正常的。
因此,对于这种特定的输入,没有感染。
Infections may not always propagate to the output
for(int j = i; j < s.length(); j++)
考虑原始缺陷会发生什么,如果输入字符串s=“stst”。
缺陷被执行,字符“s”和“t”过早地输入到副本集中,但总体输出是正确的
Test cases need to reveal failures
测试用例如何检测软件故障?
The RIPR model:
Defect Reached 😫
State Infected 🤢
Infection Propagated 🤮
Failure Revealed 🤓