Mutation Testing using Mutpy Module in Python
Last Updated :
20 Aug, 2020
Prerequisite: Mutation Testing
Mutpy is a Mutation testing tool in Python that generated mutants and computes a mutation score. It supports standard unittest module, generates YAML/HTML reports and has colorful output. It applies mutation on AST level.
Installation:
This module does not come built-in with Python. To install it type the below command in the terminal.
pip install mutpy
Here, we will use the Mutpy library to execute test cases written for a simple program.
Now, we perform Mutation Testing for a program that checks if a number is prime or not.
Code: This code is save as isPrime.py
Python3
# define a function
def isPrime(num):
if num > 1:
# check for factors
for i in range(2,num):
if (num % i) == 0:
return False
else:
return True
# if input number is less than
# or equal to 1, it is not prime
else:
return False;
Now, we need to write test cases for the above program using Pytest or Unittest library. Test cases should be written with an approach to kill all the mutants, i.e. test cases should be effective enough to give a good mutation score. The test cases are written using the Unittest library in the file shown below.
Test cases are written using self.assertEqual() that is a test assertion generally used to determine if a test case has passed or failed. We have written three test functions below to check the three types of input:
- Input is prime
- Input is non-prime
- Input is invalid
Note: The function name and the test file name should always start with the word 'test'.
Code: This code is save as test_isPrime.py.
Python3
# import required libraries
from unittest import TestCase
from isPrime import isPrime
# define a class
class CalculatorTest(TestCase):
# test case for checking non prime nums
def test_nonprime(self):
self.assertEqual(isPrime(12),False)
# test case to check prime nums
def test_prime(self):
self.assertEqual(isPrime(19),True)
# test case to check invalid input
def test_invalid(self):
self.assertEqual(isPrime(-1),False)
To execute these test cases, we need to create two separate files isPrime.py and test_isPrime.py in a single folder and run the following command in the command prompt:
mut.py --target isPrime --unit-test test_isPrime -m --runner pytest
In the above command, we have to specify three things:
- Target: the target file on which test cases will be run, which in our case is isPrime.py
- Unit-test: the file which has the unit tests that have to be executed, i.e. test_isPrime.py in our case.
- Runner: pytest or unittest
The output will be a set of mutants along with details like mutation score, the number of mutations killed, survived, etc.
[*] Start mutation process:
- targets: isPrime
- tests: test_isPrime
[*] 3 tests passed:
- test_isPrime [3.07469 s]
[*] Start mutants generation and execution:
- [# 1] AOR isPrime:
--------------------------------------------------------------------------------
3:
4: if num > 1:
5:
6: for i in range(2, num):
- 7: if num % i == 0:
+ 7: if num * i == 0:
8: return False
9: else:
10:
11: return True
--------------------------------------------------------------------------------
[1.45151 s] killed by testing program mutpy/test_isPrime.py::CalculatorTest::test_nonprime
- [# 2] COI isPrime:
--------------------------------------------------------------------------------
1:
2: def isPrime(num):
3:
- 4: if num > 1:
+ 4: if not (num > 1):
5:
6: for i in range(2, num):
7: if num % i == 0:
8: return False
--------------------------------------------------------------------------------
[1.25723 s] killed by testing program mutpy/test_isPrime.py::CalculatorTest::test_invalid
- [# 3] COI isPrime:
--------------------------------------------------------------------------------
3:
4: if num > 1:
5:
6: for i in range(2, num):
- 7: if num % i == 0:
+ 7: if not (num % i == 0):
8: return False
9: else:
10:
11: return True
--------------------------------------------------------------------------------
[1.28817 s] killed by testing program mutpy/test_isPrime.py::CalculatorTest::test_prime
- [# 4] CRP isPrime:
--------------------------------------------------------------------------------
1:
2: def isPrime(num):
3:
- 4: if num > 1:
+ 4: if num > 2:
5:
6: for i in range(2, num):
7: if num % i == 0:
8: return False
--------------------------------------------------------------------------------
[1.23510 s] survived
- [# 5] CRP isPrime:
--------------------------------------------------------------------------------
2: def isPrime(num):
3:
4: if num > 1:
5:
- 6: for i in range(2, num):
+ 6: for i in range(3, num):
7: if num % i == 0:
8: return False
9: else:
10:
--------------------------------------------------------------------------------
[1.20360 s] survived
- [# 6] CRP isPrime:
--------------------------------------------------------------------------------
3:
4: if num > 1:
5:
6: for i in range(2, num):
- 7: if num % i == 0:
+ 7: if num % i == 1:
8: return False
9: else:
10:
11: return True
--------------------------------------------------------------------------------
[1.23499 s] killed by testing program mutpy/test_isPrime.py::CalculatorTest::test_prime
- [# 7] ROR isPrime:
--------------------------------------------------------------------------------
1:
2: def isPrime(num):
3:
- 4: if num > 1:
+ 4: if num < 1:
5:
6: for i in range(2, num):
7: if num % i == 0:
8: return False
--------------------------------------------------------------------------------
[1.24164 s] killed by testing program mutpy/test_isPrime.py::CalculatorTest::test_invalid
- [# 8] ROR isPrime:
--------------------------------------------------------------------------------
1:
2: def isPrime(num):
3:
- 4: if num > 1:
+ 4: if num >= 1:
5:
6: for i in range(2, num):
7: if num % i == 0:
8: return False
--------------------------------------------------------------------------------
[1.21934 s] survived
- [# 9] ROR isPrime:
--------------------------------------------------------------------------------
3:
4: if num > 1:
5:
6: for i in range(2, num):
- 7: if num % i == 0:
+ 7: if num % i != 0:
8: return False
9: else:
10:
11: return True
--------------------------------------------------------------------------------
[1.32597 s] killed by testing program mutpy/test_isPrime.py::CalculatorTest::test_prime
[*] Mutation score [14.91747 s]: 66.7%
- all: 9
- killed: 6 (66.7%)
- survived: 3 (33.3%)
- incompetent: 0 (0.0%)
- timeout: 0 (
We can see from the output above, 6 mutants have been killed and only 3 mutant was able to survive. Also, a mutation score of 66.7% was achieved. We can further improve this mutation score by analyzing the mutants that survived the test cases and writing new or modifying test cases to kill the mutants that survived.
Similar Reads
Detect Mutation using Python
Prerequisite: Random Numbers in Python The following article depicts how Python can be used to detect a mutated DNA strand. Functions UsedgenerateDNASequence(): This method generates a random DNA strand of length 40 characters using the list of DNA bases A,C,G,T. This method returns the generated D
5 min read
Multiline String in Python
A sequence of characters is called a string. In Python, a string is a derived immutable data typeâonce defined, it cannot be altered. To change the strings, we can utilize Python functions like split, join, and replace.Python has multiple methods for defining strings. Single quotations (''), double
4 min read
Object oriented testing in Python
Prerequisite: Object-Oriented Testing Automated Object-Oriented Testing can be performed in Python using Pytest testing tool. In this article, we perform object-oriented testing by executing test cases for classes. We write a program that has one parent class called Product and three child classes -
5 min read
How to Publish Python package at PyPi using Twine module?
Python is so flexible and easy to use because of its available packages that are hosted on pypi.org, Let's see how to publish your own package on PyPi using Twine module. Requirements:You must have account of pypi.org, if don't create an accountThe twine library is created to simplify uploading pack
3 min read
SymPy | Permutation.mul_inv() in Python
Permutation.mul_inv() : mul_inv() is a sympy Python library function that returns the mul inverse other*~self, self and other have _array_form. Syntax : sympy.combinatorics.permutations.Permutation.mul_inv() Return : the mul inverse other*~self, self and other have _array_form. Code #1 : mul_inv() E
1 min read
How to Use Pytest for Efficient Testing in Python
Writing, organizing, and running tests is made easier with Pytest, a robust and adaptable testing framework for Python. Developers looking to guarantee code quality and dependability love it for its many capabilities and easy-to-use syntax. A critical component of software development is writing tes
5 min read
Identifying Test files and Functions using Pytest
The Python framework used for API testing is called Pytest. For executing and running the tests, it is crucial to identify the test files and functions. Pytest, by default, executes all the test files under a certain package which are of the format test_*.py or *_test.py, in case there is no test fi
2 min read
How to perform multiplication using CherryPy in Python?
CherryPy also known as a web application library is a Python web framework that provides a friendly interface to the HTTP protocol for Python developers. It allows developers to build web applications the same way as in traditional object-oriented Python programs. Thereby, resulting in smaller sourc
2 min read
C Extension Module using Python
Writing a simple C extension module directly using Pythonâs extension API and no other tools. It is straightforward to make a handcrafted extension module for a simple C code. But first, we have to make sure that the C code has a proper header file. Code #1 : C #include <math.h> extern int gcd
4 min read
Pytest Tutorial - Unit Testing in Python using Pytest Framework
In the process of development of applications, testing plays a crucial role. It ensures the developers that the application is error-free and the application is running as per the expectation. It should be done to ensure a seamless experience for the user. In this article, we will learn about testin
5 min read