mutant-hunter-env / tests /test_mutation_engine.py
Krishna1107's picture
Initial commit: MutantHunter — RL env for mutation-score-rewarded test generation
91487c9
from __future__ import annotations
import textwrap
from pathlib import Path
import pytest
from mutant_hunter.mutation.engine import MutationEngine
def test_generate_mutants_produces_distinct_sources() -> None:
src = "def f(x):\n return x + 1 if x == 0 else 0\n"
eng = MutationEngine()
muts = eng.generate_mutants(src)
assert len(muts) >= 4
# Every mutant's source must differ from the original.
for m in muts:
assert m.mutated_source is not None
assert m.mutated_source != src
# mutant ids are unique.
assert len({m.mutant_id for m in muts}) == len(muts)
def test_generate_mutants_covers_all_operators() -> None:
src = textwrap.dedent(
"""
def g(a, b):
x = 1 + 2
if a == b and a > 0:
return True
return False
"""
)
eng = MutationEngine()
ops = {m.operator for m in eng.generate_mutants(src)}
assert {"NCR", "ROR", "LCR", "AOR", "BCR"}.issubset(ops)
def test_generate_mutants_deterministic() -> None:
src = "def f(): return 1 + 2\n"
e1 = MutationEngine().generate_mutants(src)
e2 = MutationEngine().generate_mutants(src)
assert [m.mutant_id for m in e1] == [m.mutant_id for m in e2]
assert [m.mutated_source for m in e1] == [m.mutated_source for m in e2]
def test_baseline_report_kills_what_strong_tests_should(tmp_path: Path) -> None:
"""A strict suite must kill basic NCR mutations on a constant-returning fn."""
repo = tmp_path / "repo"
repo.mkdir()
(repo / "m.py").write_text("def f():\n return 1\n", encoding="utf-8")
tdir = repo / "tests"
tdir.mkdir()
(tdir / "test_m.py").write_text(
"from m import f\n\ndef test_f_returns_one():\n assert f() == 1\n",
encoding="utf-8",
)
eng = MutationEngine()
rpt = eng.baseline_report(
repo_dir=repo,
module_relpath=Path("m.py"),
test_dir="tests",
timeout_s=10.0,
progress_every=0,
)
assert rpt.total_mutants >= 1
# Every NCR mutant on `1` (1->2 and 1->0) must be killed.
assert rpt.killed >= 2