public static int findLast(int[] x, int y) {
for (int i = x.length - 1; i > 0; i--) {
if (x[i] == y) {
return i;
}
}
return -1;
}
/*
* If x == null throw a NullPointerException, else return
* the number of positive elements in x.
*/
public static int countPositive(int[] x) {
int count = 0;
for (int i = 0; i < x.length; i++) {
if (x[i] >= 0) {
count++;
}
}
return count;
}
/*
* If x == null throw a NullPointerException, else return
* the index of the LAST 0 in x.
* Return -1 if 0 does not occur in x.
*/
public static int lastZero(int[] x) {
for (int i = 0; i < x.length; i++) {
if (x[i] == 0) {
return i;
}
}
return -1;
}
/*
* If x == null throw a NullPointerException, else return
* the number of elements in x that are either odd or
* positive (or both).
*/
public static int oddOrPos(int[] x) {
int count = 0;
for (int i = 0; i < x.length; i++) {
if (x[i] % 2 == 1 || x[i] > 0) {
count++;
}
}
return count;
}
}
1(a) 缺陷是什么以及缺陷在哪里? [1分]
(b) 在什么条件下,方法的输入会导致它失败? [1分]
© 编写一个导致方法失败的 JUnit 测试用例。 这应该称为 [methodName]_failure。 (请注意,测试也应该失败——即,测试应该对方法的正确行为有一个断言。)[1 分]
2(a) 方法的输入是否有可能不执行缺陷? 如果是这样,请描述导致这种情况发生的方法输入所需的条件。 [1分]
(b) 如果可能(根据您对第 (a) 部分的回答),编写一个 JUnit 测试用例来演示本问题第 (a) 部分的场景。 这应该称为 [methodName]_defectNotExecuted。 [如果可以测试则得 1 分]
3(a) 输入是否可能执行缺陷但不感染程序的状态? 如果是这样,请描述导致这种情况发生的方法输入所需的条件。 [1分]
(b) 如果可能(根据您对第 (a) 部分的回答),编写一个 JUnit 测试用例来演示本问题第 (a) 部分的场景。 将其命名为 [methodName]_defectExecuted_noInfection。 [如果可以测试则得 1 分]
4(a) 输入是否可能导致感染但不会导致方法失败? (请注意,当程序语句不应算作感染时正在执行。)如果是这样,请描述导致这种情况发生的方法输入所需的条件。 [1分]
(b) 如果可能(根据您对第 (a) 部分的回答),编写一个 JUnit 测试用例来演示本问题第 (a) 部分的场景。 将其命名为 [methodName]_defectExecuted_infectionCaused_noFailure。 [如果可以测试则得 1 分]
5修复缺陷并将固定方法添加到名为 Assignment1Fixed.java 的类中。 (确保您作为问题 1 的一部分编写的测试在使用该方法的固定版本运行时通过。)[1 分]
findLast
(a) 循环终止准则是 i > 0,应该是 i >= 0。
(b) 这导致数组的第一个元素被忽略。 所以当 y 等于数组 x 的第一个元素时,该方法失败。
© 参见 findLast_failure
(a) 是,当 x 为空时。
(b) 参见 findLast_defectNotExecuted。
(a) 对于非空数组,当数组的第一个元素丢失时会发生感染。 因此,缺陷被执行并且感染不会发生——当 (1) x 为空(零长度)或 (2) y 在 x 中,但 y 不是 x 的第一个元素时。 (每个原因 1/2 分)
(b) 参见 findLast_defectExecuted_noInfection,基于上面的第二个原因。
(a) 是,当 y 不在 x 中时。 虽然缺少数组的第一个元素(因此感染),但无论如何 y 都不在 x 中,因此该方法返回正确的结果并且没有失败。
(b) 参见 findLast_defectExecuted_infectionCaused_noFailure。
countPositive
(a) 该方法将零数计为正数。 这个缺陷在方法的第三行,作为 if 条件的一部分。 应该是 if (x[i] > 0) 而不是 if (x[i] >= 0)
(b) 数组 x 中的零值包含在计数中,因此该方法返回错误值。
© 参见 countPositive_failure。
(a) 是,当输入的数组为空或长度为零时。 这意味着永远不会执行 if 条件。
(b) 参见 countPositive_defectNotExecuted。
(a) 一旦数组的其中一个元素的值为零,就会发生感染。 所以,当数组包含非零值时,确实执行了缺陷,但没有感染。 (1/2 标记仅用于仅表示正值或仅表示负值)。
(b) 参见 countPositive_defectExecuted_noInfection。
(a) 否。当 x 的一个元素等于 0 时状态被感染,但总是导致计数变量递增。 由于该方法返回计数,因此这种感染总是传播到输出。 (注意:作业没有明确要求在“不”的情况下给出原因,因此仅说“不”即可获得一分。但是,如果他们的理由不正确,仍然反馈原因。)
(b) 与 4(a) 一致,不可能进行 JUnit 测试。 (没有标记说这个!)
lastZero
(a) 该方法返回第一个零,而不是最后一个。 以相反的顺序考虑元素是错误的。 这意味着“缺陷”可以被解释为在多个地方之一,例如:
(1) for 循环头,应该以 i = x.length - 1 开始,倒数到 i = 0(即完整的循环头应该是 for (int i = x.length-1; i >= 0 ; i - ))
(2) 在 if 条件中,where 不是 x[i],而是 x[x.length - i - 1],那么 true 部分的 return 语句将是 return i+1
其他解释也是可能的。 (正确解释1分)
(b) 数组 x 中有多个零。 返回第一个零的索引,而不是最后一个。
© 参见 lastZero_failure。
(a) 如果我们说缺陷是 (1) 那么缺陷就无法避免,因为至少循环头的一部分 (int i=0) 总是被执行。
如果缺陷是 (2),则空输入数组永远不会执行缺陷。
(与 1(a) 一致的答案得 1 分)
(b) 参见 lastZero_defectNotExecuted,必然基于缺陷 2。
(a) 当循环开始以错误的顺序考虑数组值时,就会发生感染。 如果缺陷是 (1),则执行缺陷但如果数组为空或只有一个值则不会感染。
如果缺陷是 (2),则缺陷会被执行,但只要数组至少有一个值就不会感染。 如果数组只有一个值,那么它是否为零并不重要。
(与 1(a) 一致的答案得 1 分)
(b) 参见 lastZero_defectExecuted_noInfection,基于缺陷 2。基于缺陷 1 的测试也是允许的(输入数组为空)。
(a) 由于当循环开始以错误的顺序考虑数组值时会发生感染,因此当数组有两个值时会发生感染。 如果这些元素中有一个(1/2 标记)或更少(1/2 标记)为零,则不会发生故障。
(b) 参见 lastZero_defectExecuted_infectionCaused_noFailure。
oddOrPos
(a) 在该方法中,x[i] % 2 应该是 Math.abs(x[i] % 2),因为单独条件“x[i] % 2 == 1”不会包括要计算的负数 作为奇数(因为负奇数的 x[i] % 2 是 -1)。
(b) 当出现奇数负数时,该方法将失败,例如 -1,在数组中,因为返回的计数不正确。
© 参见 oddOrPoss_failure。
(a) 空或零长度数组不会执行缺陷。
(b) 参见 oddOrPoss_defectNotExecuted。
(a) 当条件 x[i] % 2 == 1 对于负数计算结果为 false 时,感染发生,因为根据方法的规范,正确的条件应该计算为 true。 因此,任何具有一个或多个非负奇数元素的数组都会执行缺陷但不会导致感染。
(b) 参见 oddOrPos_defectExecuted_noInfection。
(a) 不,一旦状态被感染,计数就会呈现错误的值,该值总是传播到输出。
(注意:作业没有明确要求在“不”的情况下给出原因,因此仅说“不”即可获得一分。但是,如果他们的理由不正确,仍然反馈原因。)
(b) 无法回答。 (没有标记说这个!)
通常当 set 为空时,方法的输入有可能不执行缺陷