4

我们只是在玩一些突变测试,但有一件事我不明白。为什么它总是试图在我的 for-each 循环上应用“否定条件修改器”,如下所示:

for (final Order order : orders)

如果我看一下 mutator 的描述(http://pitest.org/quickstart/mutators/#NEGATE_CONDITIONALS),那么它应该只是改变条件,比如!=to==<to >=。所以我真的不明白为什么在那里使用它以及为什么它有时会失败而有时不会。

有人可以向我解释一下吗?

4

1 回答 1

6

这是 PIT 改变字节码而不是源代码的结果。

for each 循环的字节码看起来像

INVOKEINTERFACE java/util/List.iterator ()Ljava/util/Iterator;
ASTORE 2
L2
ALOAD 2
INVOKEINTERFACE java/util/Iterator.hasNext ()Z
IFEQ L3
ALOAD 2
INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object;
<contents of the loop>
GOTO L2
L3

所以基本上在幕后它是创建一个迭代器并检查 hasNext 的值。虽然这是真的,但它通过跳转到 L2 来执行循环。

条件突变是对 IFEQ L3 调用检查 hasNext 的返回码以退出循环。

如果 PIT 可以检测到每个循环生成的条件语句,那就太好了。我不确定我是否曾经看过这种特殊情况,但总的来说,区分由语言特性生成的字节码和直接映射回开发人员编写的代码的字节码要么是困难的,要么是不可能的。

更新 - 从 1.2.5 开始,pitest 应该避免改变每个循环的条件。

于 2016-07-27T09:24:46.590 回答