Sitemap

Mutation Testing?

3 min readMar 25, 2024

--

While I’m reading “effective testing” book, I found the word that is “mutation testing”. I was wondering about the meaning of it, and I immediately searched it.

This way of testing is so mind-blowing for me. I’ve never heard about it before. The way of testing is making mutation for checking our test-system to check exceptional cases as well. It’s too long to write in Summary. So, Let’s dive into what “mutation testing” is!

Mutation Testing

As I said earlier, mutation testing change source code (in Pitest for Java manipulate java-bytecode). We call this action “mutate”. For example, there are some operations that mutate our code.

Press enter or click to view image in full size
if (a < b) {
// do something
}

After mutation, this code would be changed to “≤” like the below one.

if (a <= b) {
// do something
}

There are this kind of operation that change our code. You may have questions like “what mutation testing for?”. So, I’ll show you some simple example to show the purpose of mutation testing.

Mutation Testing in practice

In this article, I’m gonna use “kotiln”, “kotest”, and “pitest”. So, If you are not familiar with these stuff. Then you just clone my repository and execut it. It would be enough to understand the concept of “mutation testing”

Get Roach’s stories in your inbox

Join Medium for free to get updates from this writer.

Let’s say there are developer who is called by “roach” (is his a.k.a). Roach want to get off work after finishing his last task. His last work is just writing test code to verify the below function.

package com.example

class NCondition {

fun fooIfIsNumberIsPositive(number: Int): String =
if (number > 0) "foo" else "bar"
}

As saw this function, roach said, like “Oh, It’s a piece of cake!!”, and wrote the test code like the below one.

package com.example

import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe

class NConditionTest : FunSpec({

context("fooIfIsNumberIsPositive") {
test("should return foo if number is positive") {
NCondition().fooIfIsNumberIsPositive(5) shouldBe "foo"
}

test("should return bar if number is zero") {
NCondition().fooIfIsNumberIsPositive(-1) shouldBe "bar"
}
}
})

It seems to be nice and concise test code for verifying the function, and roach thought of the same as we think. Before getting off work, Roach just executed pitest just in case.

Press enter or click to view image in full size

And the report from pitest told that “your test case is not enough for detecting changes! One mutation survived, even though, it was executed by test case in our system!!”

Roach composed himself again, and looked at the report again. The report told roach, it’s success even we changed your conditional boundary(`>` to `=>`) to the other boundary, then your test case is success!

So Roach thought about what would happen if the conditional boundary changed. Roach just came up with the phrase from this book, which was “you always should pay attention to the boundary value”. After while, roach realized that he should write test code for “zero”. As soon as he wrote test code, and executed it, the mutation died!

Press enter or click to view image in full size

In conclusion

As you saw this article, the mutation testing can help you to find the exceptional case, and make your testing-system more robust based on the result. But, That doesn’t mean it’s a perfect fit everywhere. You should be more careful, if you want to put this one into your project. You should think about what you can get from the result, like this.

If you want to talk about the advantages of using this kind of mutation testing on production level, please feel free to DM me. I’d like to chat with you guys who are interested in this topic.

Linked-In: https://www.linkedin.com/in/%EC%8A%B9%ED%98%84-%EC%A0%95-376842221/?locale=en_US

--

--