Pitest变异测试报negated conditional→SURVIVED的解决方法
问题根因
首先明确negated conditional变异的实际效果:Pitest会将三元表达式的判断条件取反,你这段代码变异后等价于如下逻辑:
result = test == null ? test : "";
你之前编写的测试用例无法杀死变异体,核心原因有两个:
- 部分测试输入属于等价输入:原代码和变异代码在该输入下返回值完全一致,根本无法区分逻辑差异
- 断言写法存在严重错误,没有正确校验逻辑的实际返回结果,导致可被检测的差异没有被捕获
原有测试用例失效分析
逐个对应你写的三个测试场景:
- test赋值为
""(空字符串)时:
原代码判断test非null,返回第一个分支的test值也就是"";变异后判断test不等于null,走第二个分支返回""。两者输出完全相同,这个用例从根本上不可能杀死变异体,属于无效用例。 - test赋值为
null时:
原代码返回第二个分支的"",变异后返回第一个分支的null,两者输出存在明显差异,但你写的asserThat(testValue.equals(""))存在拼写错误(assertThat少写了t),且不符合assertThat的语法要求(未传入匹配器),甚至大概率你校验的对象是入参test而非逻辑执行后的返回值result,导致差异没有被断言捕获。 - test赋值为
"value"这类非空字符串时:
原代码返回第一个分支的"value",变异后返回第二个分支的"",输出差异同样明显,但还是因为你的断言写法错误,没有正确校验result值,没能杀死变异体。
正确测试用例编写方法
你只需要编写2个有效用例,避开等价输入,写对返回值断言即可覆盖该变异:
- null入参场景:test赋值为null,断言返回值为空字符串
""
此时变异代码会返回null,和预期值不符,变异会被杀死 - 非空非空串入参场景:test赋值为任意非null、且不等于
""的字符串(比如"unitTest"),断言返回值和输入的test值完全相等
此时变异代码会返回空字符串"",和预期值不符,变异会被杀死
参考测试代码(JUnit5实现):
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class NullCheckTest { // 覆盖null入参场景 @Test void shouldReturnEmptyStringWhenInputIsNull() { String test = null; String result = test != null ? test : ""; assertEquals("", result); } // 覆盖非空有效值入参场景 @Test void shouldReturnOriginalValueWhenInputIsNonNullNonEmpty() { String test = "validValue"; String result = test != null ? test : ""; assertEquals("validValue", result); } }
注意:不需要保留test赋值为空字符串的测试用例,该输入属于等价输入,对杀死这个条件取反变异没有任何帮助。
内容的提问来源于stack exchange,提问作者RagaSGNur
相关产品推荐
相关产品推荐

