Mutations¶
mutatest supports the following mutation operations based on the Python AST grammar 1:
- Supported operations:
AugAssignmutations e.g.+= -= *= /=.BinOpmutations e.g.+ - / *.BinOp Bitwise Comparisonmutations e.g.x&y x|y x^y.BinOp Bitwise Shiftmutations e.g.<< >>.BoolOpmutations e.g.and or.Comparemutations e.g.== >= < <= !=.Compare Inmutations e.g.in, not in.Compare Ismutations e.g.is, is not.Ifmutations e.g.If x > ybecomesIf TrueorIf False.Indexmutations e.g.i[0]becomesi[1]andi[-1].NameConstantmutations e.g.True,False, andNone.Slicemutations e.g. changingx[:2]tox[2:].
These are the current operations that are mutated as compatible sets. The two-letter category code for white/black-list selection is beside the name in double quotes.
AugAssign - “aa”¶
Augmented assignment e.g. += -= /= *=.
- Members:
AugAssign_AddAugAssign_DivAugAssign_MultAugAssign_Sub
Example:
# source code
x += y
# mutations
x -= y # AugAssign_Sub
x *= y # AugAssign_Mult
x /= y # AugAssign_Div
BinOp - “bn”¶
Binary operations e.g. add, subtract, divide, etc.
- Members:
ast.Addast.Divast.FloorDivast.Modast.Multast.Powast.Sub
Example:
# source code
x = a + b
# mutations
x = a / b # ast.Div
x = a - b # ast.Sub
BinOp Bit Comparison - “bc”¶
Bitwise comparison operations e.g. x & y, x | y, x ^ y.
- Members:
ast.BitAndast.BitOrast.BitXor
Example:
# source code
x = a & y
# mutations
x = a | y # ast.BitOr
x = a ^ y # ast.BitXor
BinOp Bit Shifts - “bs”¶
Bitwise shift operations e.g. << >>.
- Members:
ast.LShiftast.RShift
Example:
# source code
x >> y
# mutation
x << y
BoolOp - “bl”¶
Boolean operations e.g. and or.
- Members:
ast.Andast.Or
Example:
# source code
if x and y:
# mutation
if x or y:
Compare - “cp”¶
Comparison operations e.g. == >= <= > <.
- Members:
ast.Eqast.Gtast.GtEast.Ltast.LtEast.NotEq
Example:
# source code
x >= y
# mutations
x < y # ast.Lt
x > y # ast.Gt
x != y # ast.NotEq
Compare In - “cn”¶
Compare membership e.g. in, not in.
- Members:
ast.Inast.NotIn
Example:
# source code
x in [1, 2, 3, 4]
# mutation
x not in [1, 2, 3, 4]
Compare Is - “cs”¶
Comapre identity e.g. is, is not.
- Members:
ast.Isast.IsNot
Example:
# source code
x is None
# mutation
x is not None
If - “if”¶
If mutations change if statements to always be True or False. The original
statement is represented by the class If_Statement in reporting.
- Members:
If_FalseIf_StatementIf_True
Example:
# source code
if a > b: # If_Statement
...
# Mutations
if True: # If_True
...
if False: # If_False
...
Index - “ix”¶
Index values for iterables e.g. i[-1], i[0], i[0][1]. It is worth noting that this is a
unique mutation form in that any index value that is positive will be marked as Index_NumPos
and the same relative behavior will happen for negative index values to Index_NumNeg. During
the mutation process there are three possible outcomes: the index is set to 0, -1 or 1.
The alternate values are chosen as potential mutations e.g. if the original operation is classified
as Index_NumPos such as x[10] then valid mutations are to x[0] or
x[-1].
- Members:
Index_NumNegIndex_NumPosIndex_NumZero
Example:
# source code
x = [a[10], a[-4], a[0]]
# mutations
x = [a[-1], a[-4], a[0]] # a[10] mutated to Index_NumNeg
x = [a[10], a[0], a[0]] # a[-4] mutated to Index_NumZero
x = [a[10], a[1], a[0]] # a[-4] mutated to Index_NumPos
x = [a[10], a[-4], a[1]] # a[0] mutated to Index_NumPos
NameConstant - “nc”¶
Named constant mutations e.g. True, False, None.
- Members:
FalseNoneTrue
Example:
# source code
x = True
# mutations
x = False
X = None
Slices - “su”¶
Slice mutations to swap lower/upper values, or change range e.g. x[2:] to x[:2].
This is a unique mutation. If the upper or lower bound is set to
None then the bound values are swapped. This is represented by the operations of
Slice_UnboundedUpper for swap None to the “upper” value from “lower”. The category code
for this type of mutation is “su”.
- Members:
Slice_UnboundedSlice_UnboundedLowerSlice_UnboundedUpper
Example:
# source code
w = a[:2]
x = a[4:]
# mutation
w = a[2:] # Slice_UnboundedUpper, upper is now unbounded and lower has a value
x = a[4:]
# mutation
w = a[:2]
x = a[:4] # Slice_UnboundedLower, lower is now unbounded and upper has a value
# mutation
w = a[:2]
x = a[:] # Slice_Unbounded, both upper and lower are unbounded