如何重构幸存的突变以获得try-resource和等效的突变体?



我正在试验junit5和pitest。 我测试的代码如下所示:

// [...]
InputStream istream = this.getClass().getResourceAsStream("/" + file.getName());
if (istream == null) // 1. negated condition -> suvived 
{
istream = Files.newInputStream(this.files.get(varname).toPath(), StandardOpenOption.READ);
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(istream, StandardCharsets.UTF_8))) // 2. removed call to java/io/BufferedReader::close → SURVIVED // 3. removed call to java/lang/Throwable::addSuppressed → SURVIVED
{
// [...]
} // 4. removed call to java/io/BufferedReader::close → SURVIVED

在这个小代码块中,我留下了 4 个幸存的突变,我想杀死。通过添加/更改测试或重构代码可能会发生杀戮。

我的问题是现在第一个突变是一个等效的突变体——我不知道如何重构它。 其他三个突变被try-resource-语句隐含。

所以我的问题是如何重构这 4 个突变?因为我确信它们不会被额外/更改的测试杀死。

仅当函数的可观察行为在 if 语句的两边相同时,第一个突变体是等效的。

要做到这一点,"file"和"this.files.get(varname)"需要始终解析为相同的输入流。

如果它们可以解析为不同的输入流,则可以构建一个测试来杀死突变体。

如果他们总是会解决同一件事,那么为什么需要第一个分支?除非存在一些无法测试的问题(例如性能),否则不需要第一个分支,并且始终可以从"this.files.get(varname).toPath()"解析流。

其他变种人有点棘手。

它们是等效的,因为它们处理非单元可测试的问题(资源管理)。更重要的是,它们是"垃圾",因为它们是编译器构造,不会直接映射回代码。

Pitest试图过滤掉像这样的垃圾突变体,但过滤是不完美的,因为它们没有在字节码中明确标识为编译器结构。

如果我将您的代码片段粘贴到文件中并进行编辑以便编译,则 1.4.8 版本会正确过滤掉所有这些突变体。如果您可以粘贴一个重现该问题的完整可编译类,我可以看到是否可以调整过滤以在上下文中拾取这些突变体。

最新更新