PiTest "changed conditional boundary mutation survived" 无故?
PiTest "changed conditional boundary mutation survived" without reason?
我有一个小的 Java 11 示例,其中包含 JUnit 5 测试,结果最差:
changed conditional boundary → SURVIVED
主要class:
public final class CheckerUtils
{
private CheckerUtils()
{
super();
}
public static int checkPort(final int port)
{
if (port < 0)
{
throw new IndexOutOfBoundsException("Port number out of range!");
}
return port;
}
}
测试class:
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import de.powerstat.security.CheckerUtils;
public final class CheckerUtilsTests
{
@Test
public void checkPortOk()
{
final int port = 1023;
final int resultPort = CheckerUtils.checkPort(port);
assertEquals(port, resultPort, "Port not as expected!");
}
@Test
public void checkPortNegative1()
{
final int port = -1;
assertThrows(IndexOutOfBoundsException.class, () ->
{
CheckerUtils.checkPort(port);
}
);
}
@Test
public void checkPortNegative2()
{
final int port = -1;
int resultPort = 0;
try
{
resultPort = CheckerUtils.checkPort(port);
}
catch (final IndexOutOfBoundsException e)
{
// ignore
}
assertEquals(0, resultPort, "Port is not 0");
}
}
从我的角度来看,突变不应该存活,因为:
- checkPortOk() 是非负合法值的正常路径
- checkPortNegative1() 是 note 发生突变并抛出异常时负值的路径。
- checkPortNegative2(): 当没有任何变化时,抛出异常并且 resultPort 仍然是 0 - 所以这里的断言是正确的
- checkPortNegative2(): 当 < 0 突变为 < -1 或更低时,则不会抛出异常,因此 resultPort 将变为 -1,断言将失败(突变被杀死)
- checkPortNegative2(): 当< 0 突变为< 1 或更高时,与3 下相同。
所以我的问题是我在这里遗漏了什么还是 pitest (1.4.9) 中的错误?
解决方案
正如@henry 所说,添加以下测试解决了问题:
@Test
public void checkPortOk2()
{
final int port = 0;
final int resultPort = CheckerUtils.checkPort(port);
assertEquals(port, resultPort, "Port not as expected!");
}
条件边界突变会发生突变
if (port < 0)
到
if (port <= 0)
由于 none 的测试提供的输入为 0,因此它们无法将突变体与未突变的程序区分开来,突变体将存活下来。
添加一个描述端口为 0 时预期行为的测试用例应该会杀死突变体。
我有一个小的 Java 11 示例,其中包含 JUnit 5 测试,结果最差:
changed conditional boundary → SURVIVED
主要class:
public final class CheckerUtils
{
private CheckerUtils()
{
super();
}
public static int checkPort(final int port)
{
if (port < 0)
{
throw new IndexOutOfBoundsException("Port number out of range!");
}
return port;
}
}
测试class:
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import de.powerstat.security.CheckerUtils;
public final class CheckerUtilsTests
{
@Test
public void checkPortOk()
{
final int port = 1023;
final int resultPort = CheckerUtils.checkPort(port);
assertEquals(port, resultPort, "Port not as expected!");
}
@Test
public void checkPortNegative1()
{
final int port = -1;
assertThrows(IndexOutOfBoundsException.class, () ->
{
CheckerUtils.checkPort(port);
}
);
}
@Test
public void checkPortNegative2()
{
final int port = -1;
int resultPort = 0;
try
{
resultPort = CheckerUtils.checkPort(port);
}
catch (final IndexOutOfBoundsException e)
{
// ignore
}
assertEquals(0, resultPort, "Port is not 0");
}
}
从我的角度来看,突变不应该存活,因为:
- checkPortOk() 是非负合法值的正常路径
- checkPortNegative1() 是 note 发生突变并抛出异常时负值的路径。
- checkPortNegative2(): 当没有任何变化时,抛出异常并且 resultPort 仍然是 0 - 所以这里的断言是正确的
- checkPortNegative2(): 当 < 0 突变为 < -1 或更低时,则不会抛出异常,因此 resultPort 将变为 -1,断言将失败(突变被杀死)
- checkPortNegative2(): 当< 0 突变为< 1 或更高时,与3 下相同。
所以我的问题是我在这里遗漏了什么还是 pitest (1.4.9) 中的错误?
解决方案
正如@henry 所说,添加以下测试解决了问题:
@Test
public void checkPortOk2()
{
final int port = 0;
final int resultPort = CheckerUtils.checkPort(port);
assertEquals(port, resultPort, "Port not as expected!");
}
条件边界突变会发生突变
if (port < 0)
到
if (port <= 0)
由于 none 的测试提供的输入为 0,因此它们无法将突变体与未突变的程序区分开来,突变体将存活下来。
添加一个描述端口为 0 时预期行为的测试用例应该会杀死突变体。