Mutation testing booleans with Java

1.8k views Asked by At

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

There are 1 answers

2
henry On

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.