突变测试布尔值与Java

huangapple go评论95阅读模式
英文:

Mutation testing booleans with Java

问题

以下是翻译好的内容:

我对Java几乎没有经验,我遇到了一些问题。

我有一个类似下面的代码,并且目标是消除其中的所有变异。

public class MyClass {

  protected transient boolean something = false;

  public MyClass () {
    something = true;
  }

  boolean isSomething () {
    return something;
  }

}

我的测试代码如下所示

tester = MyClass();
assertTrue(tester.isSomething());

在Eclipse上用pitest运行它,会生成以下变异(都与return something语句有关):

  1. 用0替换了1
  2. 移除了对成员变量something的赋值
  3. 用0替换了1
  4. 用-1替换了1
  5. 用-1替换了1
  6. 用2替换了1
  7. 用0替换了1

不幸的是,我就是无法消除那4和5的变异,它们都将1替换为-1。有办法我能消除它们吗?

英文:

I have very very little experience with Java and I'm facing some issues.

I've got a code that looks like the one below and a goal to kill all mutations of it.

public class MyClass {

  protected transient boolean something = false;

  public MyClass () {
    something = true;
  }

  boolean isSomething () {
    return something;
  }

}

My test code looks like this

tester = MyClass();
assertTrue(tester.isSomething());

By running it with pitest, on Eclipse, it would generate the following mutations (all related to the return something statement):

  1. Substituted 1 with 0
  2. Removed assignment to member variable something
  3. Substituted 1 with 0
  4. Substituted 1 with -1
  5. Substituted 1 with -1
  6. Substituted 1 with 2
  7. Substituted 1 with 0

Unfortunately, I just can't kill those 4 and 5 mutations, both that substitutes 1 with -1. Is there a way I could kill them?

答案1

得分: 2

这里有一些问题。

首先,您似乎启用了一些实验性/研究性的突变操作,这些操作会生成无用的突变。如果您坚持使用默认设置,就不会出现这种情况。

在 jvm 级别,布尔值被表示为 0/1 的整数。只有以下突变才有意义:

  • 用 0 替换了 1
  • 移除对成员变量 something 的赋值

(请注意,尽管在这种情况下突变是有意义的,但默认情况下禁用了删除成员赋值,因为它可能产生等效的突变)

由于您没有提供完整的上下文,重复的 1/0 替换是重复的还是不同的就不清楚。

要消除这些突变体,有两种方法。首先,删除冗余代码。

public class MyClass {

  protected transient boolean something = true;

  boolean isSomething() {
    return something;
  }

}

这在功能上等同于原始代码,但代码量较少。

其次,您需要编写测试。

由于您将 something 设置为受保护,我假设 MyClass 有子类?如果没有的话,代码可以进一步简化为:

public class MyClass {

  boolean isSomething() {
    return true;
  }

}

并且您只能编写一个测试。

assertThat(new MyClass().isSomething()).isTrue();

如果有子类,那么您需要编写测试来检查设置 something 为 true,然后断言 isSomething 返回 true;另一个测试设置为 false,并断言方法返回 false。

英文:

There are a few issues here.

Firstly you look to have some experimental/research mutation operators enabled which are generating junk mutations. This will not happen if you stick with the default set.

As at the jvm level booleans are represented as integers of 0/1. Only the following mutations make sense

  • Substituted 1 with 0
  • Removed assignment to member variable something

(note that although the mutation makes sense in this case, the removal of member assignments is disabled by default as it can produce equivalent mutants)

You don't provide the full context so it is not clear if the repeated 1/0 substitutions are duplicates or distinct.

To kill these mutants there are two approaches. Firstly remove redundant code.

public class MyClass {

  protected transient boolean something = true;

  boolean isSomething () {
    return something;
  }

}

This is functionaly equivalent to the original code, but there is less of it.

Secondly you need tests.

Since you have made something protected I assume that MyClass has subclasses? If it does not then then code could be further reduced down to

public class MyClass {

  boolean isSomething () {
    return true;
  }

}

And there is only one test you can write.

assertThat(new MyClass().isSomething()).isTrue();

If there are subclasses then you need tests that check that setup something to be true, and then assert that isSomething returns true, and another that sets it up to be false and asserts the method returns false.

huangapple
  • 本文由 发表于 2020年10月13日 23:28:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/64338300.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定