- if quantity <= 0:+ if quantity < 0:
`<=` -> `<` in `quantity <= 0`
Add a test at the boundary where this comparison flips.
Scope: all files · 63 mutants generated · 10 tests collected
Showing 24 mutants. Press / to search, Esc to reset.
- if quantity <= 0:+ if quantity < 0:
`<=` -> `<` in `quantity <= 0`
Add a test at the boundary where this comparison flips.
- raise ValueError("quantity must be positive")+ raise ValueError("")
string 'quantity must be positive' -> ""
Assert against a different value so this constant is observable.
- self.items.append({"sku": sku, "price": price, "quantity": quantity})+ self.items.append({"": sku, "price": price, "quantity": quantity})
string 'sku' -> ""
Assert against a different value so this constant is observable.
- sum(float(item["price"]) * int(item["quantity"]) for item in self.items), 2+ sum(float(item["price"]) * int(item["quantity"]) for item in self.items), 3
`2` -> `3`
Assert against a different value so this constant is observable.
- return round(subtotal - discount + shipping, 2)+ return round(subtotal - discount + shipping, 3)
`2` -> `3`
Assert against a different value so this constant is observable.
- if count < 0:+ if count <= 0:
`<` -> `<=` in `count < 0`
Add a test at the boundary where this comparison flips.
- if count < 0:+ if count < 1:
`0` -> `1`
Assert against a different value so this constant is observable.
- raise ValueError("cannot add a negative count")+ raise ValueError("")
string 'cannot add a negative count' -> ""
Assert against a different value so this constant is observable.
- available = self.stock.get(sku, 0)+ available = self.stock.get(sku, 1)
`0` -> `1`
Assert against a different value so this constant is observable.
- if count > available:+ if count >= available:
`>` -> `>=` in `count > available`
Add a test at the boundary where this comparison flips.
- return True+ return None
`return True` -> `return None`
Assert the return value; calling the function is not enough.
- return True+ return False
`True` -> `False`
Assert against a different value so this constant is observable.
- return self.stock.get(sku, 0)+ return self.stock.get(sku, 1)
`0` -> `1`
Assert against a different value so this constant is observable.
- FREE_SHIPPING_THRESHOLD = 100.0+ FREE_SHIPPING_THRESHOLD = 101.0
`100.0` -> `101.0`
Assert against a different value so this constant is observable.
- EXPRESS_FEE = 9.99+ EXPRESS_FEE = 10.99
`9.99` -> `10.99`
Assert against a different value so this constant is observable.
- "basic": 0.0,+ "": 0.0,
string 'basic' -> ""
Assert against a different value so this constant is observable.
- "gold": 0.10,+ "": 0.10,
string 'gold' -> ""
Assert against a different value so this constant is observable.
- "gold": 0.10,+ "gold": 1.1,
`0.1` -> `1.1`
Assert against a different value so this constant is observable.
- return TIER_RATES.get(tier, 0.0)+ return TIER_RATES.get(tier, 1.0)
`0.0` -> `1.0`
Assert against a different value so this constant is observable.
- if total >= FREE_SHIPPING_THRESHOLD and tier == "gold":+ if total > FREE_SHIPPING_THRESHOLD and tier == "gold":
`>=` -> `>` in `total >= FREE_SHIPPING_THRESHOLD`
Add a test at the boundary where this comparison flips.
- return round(total * 0.15, 2)+ return round(total * 0.15, 3)
`2` -> `3`
Assert against a different value so this constant is observable.
- return round(total * discount_rate(tier), 2)+ return round(total * discount_rate(tier), 3)
`2` -> `3`
Assert against a different value so this constant is observable.
- return EXPRESS_FEE+ return None
`return EXPRESS_FEE` -> `return None`
Assert the return value; calling the function is not enough.
- if total >= FREE_SHIPPING_THRESHOLD:+ if total > FREE_SHIPPING_THRESHOLD:
`>=` -> `>` in `total >= FREE_SHIPPING_THRESHOLD`
Add a test at the boundary where this comparison flips.
- if quantity <= 0:+ if not (quantity <= 0):
negate condition `quantity <= 0`
Test the branch this condition guards, not only the happy path.
- if quantity <= 0:+ if quantity <= 1:
`0` -> `1`
Assert against a different value so this constant is observable.
- self.items.append({"sku": sku, "price": price, "quantity": quantity})+ pass
remove `self.items.append({"sku": sku, "price": price, "quantity": qu...`
Assert the side effect of this call (state, output, or log).
- self.items.append({"sku": sku, "price": price, "quantity": quantity})+ self.items.append({"sku": sku, "": price, "quantity": quantity})
string 'price' -> ""
Assert against a different value so this constant is observable.
- self.items.append({"sku": sku, "price": price, "quantity": quantity})+ self.items.append({"sku": sku, "price": price, "": quantity})
string 'quantity' -> ""
Assert against a different value so this constant is observable.
- return round( sum(float(item["price"]) * int(item["quantity"]) for item in self.items), 2 )+ return None
`return round( sum(float(item["price"]) * int(item["quantity"]...` -> `return None`
Assert the return value; calling the function is not enough.
- sum(float(item["price"]) * int(item["quantity"]) for item in self.items), 2+ sum(float(item[""]) * int(item["quantity"]) for item in self.items), 2
string 'price' -> ""
Assert against a different value so this constant is observable.
- sum(float(item["price"]) * int(item["quantity"]) for item in self.items), 2+ sum(float(item["price"]) / int(item["quantity"]) for item in self.items), 2
`*` -> `/` in `float(item["price"]) * int(item["quantity"])`
Assert the exact numeric result, not just its type.
- sum(float(item["price"]) * int(item["quantity"]) for item in self.items), 2+ sum(float(item["price"]) * int(item[""]) for item in self.items), 2
string 'quantity' -> ""
Assert against a different value so this constant is observable.
- return round(subtotal - discount + shipping, 2)+ return None
`return round(subtotal - discount + shipping, 2)` -> `return None`
Assert the return value; calling the function is not enough.
- return round(subtotal - discount + shipping, 2)+ return round(subtotal + discount + shipping, 2)
`-` -> `+` in `subtotal - discount`
Assert the exact numeric result, not just its type.
- return round(subtotal - discount + shipping, 2)+ return round(subtotal - discount - shipping, 2)
`+` -> `-` in `subtotal - discount + shipping`
Assert the exact numeric result, not just its type.
- return len(self.items)+ return None
`return len(self.items)` -> `return None`
Assert the return value; calling the function is not enough.
- if count < 0:+ if not (count < 0):
negate condition `count < 0`
Test the branch this condition guards, not only the happy path.
- self.stock[sku] = self.stock.get(sku, 0) + count+ self.stock[sku] = self.stock.get(sku, 1) + count
`0` -> `1`
Assert against a different value so this constant is observable.
- self.stock[sku] = self.stock.get(sku, 0) + count+ self.stock[sku] = self.stock.get(sku, 0) - count
`+` -> `-` in `self.stock.get(sku, 0) + count`
Assert the exact numeric result, not just its type.
- if count > available:+ if not (count > available):
negate condition `count > available`
Test the branch this condition guards, not only the happy path.
- raise ValueError("not enough stock for %s" % sku)+ raise ValueError("" % sku)
string 'not enough stock for %s' -> ""
Assert against a different value so this constant is observable.
- self.stock[sku] = available - count+ self.stock[sku] = available + count
`-` -> `+` in `available - count`
Assert the exact numeric result, not just its type.
- return self.stock.get(sku, 0)+ return None
`return self.stock.get(sku, 0)` -> `return None`
Assert the return value; calling the function is not enough.
- STANDARD_FEE = 4.99+ STANDARD_FEE = 5.99
`4.99` -> `5.99`
Assert against a different value so this constant is observable.
- "basic": 0.0,+ "basic": 1.0,
`0.0` -> `1.0`
Assert against a different value so this constant is observable.
- "silver": 0.05,+ "": 0.05,
string 'silver' -> ""
Assert against a different value so this constant is observable.
- "silver": 0.05,+ "silver": 1.05,
`0.05` -> `1.05`
Assert against a different value so this constant is observable.
- return TIER_RATES.get(tier, 0.0)+ return None
`return TIER_RATES.get(tier, 0.0)` -> `return None`
Assert the return value; calling the function is not enough.
- if total >= FREE_SHIPPING_THRESHOLD and tier == "gold":+ if not (total >= FREE_SHIPPING_THRESHOLD and tier == "gold"):
negate condition `total >= FREE_SHIPPING_THRESHOLD and tier == "gold"`
Test the branch this condition guards, not only the happy path.
- if total >= FREE_SHIPPING_THRESHOLD and tier == "gold":+ if total >= FREE_SHIPPING_THRESHOLD or tier == "gold":
`and` -> `or` in `total >= FREE_SHIPPING_THRESHOLD and tier == "gold"`
Cover a case where only one operand is true.
- if total >= FREE_SHIPPING_THRESHOLD and tier == "gold":+ if total >= FREE_SHIPPING_THRESHOLD and tier != "gold":
`==` -> `!=` in `tier == "gold"`
Add a test at the boundary where this comparison flips.
- if total >= FREE_SHIPPING_THRESHOLD and tier == "gold":+ if total >= FREE_SHIPPING_THRESHOLD and tier == "":
string 'gold' -> ""
Assert against a different value so this constant is observable.
- return round(total * 0.15, 2)+ return None
`return round(total * 0.15, 2)` -> `return None`
Assert the return value; calling the function is not enough.
- return round(total * 0.15, 2)+ return round(total / 0.15, 2)
`*` -> `/` in `total * 0.15`
Assert the exact numeric result, not just its type.
- return round(total * 0.15, 2)+ return round(total * 1.15, 2)
`0.15` -> `1.15`
Assert against a different value so this constant is observable.
- return round(total * discount_rate(tier), 2)+ return None
`return round(total * discount_rate(tier), 2)` -> `return None`
Assert the return value; calling the function is not enough.
- return round(total * discount_rate(tier), 2)+ return round(total / discount_rate(tier), 2)
`*` -> `/` in `total * discount_rate(tier)`
Assert the exact numeric result, not just its type.
- if express:+ if not (express):
negate condition `express`
Test the branch this condition guards, not only the happy path.
- if total >= FREE_SHIPPING_THRESHOLD:+ if not (total >= FREE_SHIPPING_THRESHOLD):
negate condition `total >= FREE_SHIPPING_THRESHOLD`
Test the branch this condition guards, not only the happy path.
- return 0.0+ return None
`return 0.0` -> `return None`
Assert the return value; calling the function is not enough.
- return 0.0+ return 1.0
`0.0` -> `1.0`
Assert against a different value so this constant is observable.
- return STANDARD_FEE+ return None
`return STANDARD_FEE` -> `return None`
Assert the return value; calling the function is not enough.
| file | killed | survived | score | |
|---|---|---|---|---|
| shop/cart.py | 13 | 5 | 72% | |
| shop/inventory.py | 7 | 8 | 47% | |
| shop/pricing.py | 19 | 11 | 63% |
Mutation score is the share of generated mutants your suite detected. A mutant is a small, syntactically valid change to your code: a flipped comparison, a changed constant, a removed return value. If the suite still passes, the mutant survived, which means no test observed that behaviour.
Survivors are not automatically bugs. Some mutants are equivalent (the change cannot alter observable behaviour, such as changing the rounding precision of a value that is already exact). Treat survivors as questions, not verdicts. The hint on each card suggests the kind of assertion that would settle it.
Fang only mutates the lines in scope, runs the suite with fail-fast, and treats a timeout or a crash caused by the mutant as detection. A green baseline is required; a red suite cannot distinguish a surviving mutant from a pre-existing failure.