2023-12-09 19:52:07 +00:00
|
|
|
import argparse
|
|
|
|
import os
|
2023-12-22 16:23:43 +00:00
|
|
|
import re
|
|
|
|
from collections import defaultdict
|
|
|
|
|
|
|
|
import pandas as pd
|
|
|
|
from tqdm import tqdm
|
|
|
|
|
2023-12-20 13:19:45 +00:00
|
|
|
from mutpy import commandline
|
2023-12-22 16:23:43 +00:00
|
|
|
import sys
|
|
|
|
from io import StringIO
|
|
|
|
import contextlib
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
from typing import List, Dict, DefaultDict
|
2023-12-20 13:19:45 +00:00
|
|
|
|
2023-12-09 19:52:07 +00:00
|
|
|
ROOT_DIR = os.path.dirname(__file__)
|
|
|
|
IN_SOURCE_DIR = os.path.join(ROOT_DIR, "benchmark")
|
|
|
|
IN_TEST_DIR = os.path.join(ROOT_DIR, "tests")
|
|
|
|
OUT_DIR = os.path.join(ROOT_DIR, "tests")
|
2023-12-22 16:23:43 +00:00
|
|
|
MUT_PY_PATH = os.path.join(ROOT_DIR, 'env37', 'bin', 'mut.py')
|
|
|
|
REPS: int = 10
|
|
|
|
|
|
|
|
|
|
|
|
class OutputCapture():
|
|
|
|
result: str
|
2023-12-09 19:52:07 +00:00
|
|
|
|
|
|
|
|
2023-12-22 16:23:43 +00:00
|
|
|
@contextlib.contextmanager
|
|
|
|
def capture_stdout():
|
|
|
|
old = sys.stdout
|
|
|
|
capturer = StringIO()
|
|
|
|
sys.stdout = capturer
|
2023-12-20 13:19:45 +00:00
|
|
|
|
2023-12-22 16:23:43 +00:00
|
|
|
data = OutputCapture()
|
|
|
|
yield data
|
2023-12-20 13:19:45 +00:00
|
|
|
|
2023-12-22 16:23:43 +00:00
|
|
|
sys.stdout = old
|
|
|
|
data.result = capturer.getvalue()
|
2023-12-18 14:13:31 +00:00
|
|
|
|
2023-12-22 16:23:43 +00:00
|
|
|
|
|
|
|
def run_mutpy(test_path: str, source_path: str) -> float:
|
|
|
|
output = subprocess.check_output(
|
|
|
|
[sys.executable, MUT_PY_PATH, '-t', source_path, '-u', test_path]).decode('utf-8')
|
|
|
|
score = re.search('Mutation score \\[.*]: (\\d+\\.\\d+)%', output).group(1)
|
|
|
|
return float(score)
|
2023-12-09 19:52:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
def main():
|
2023-12-21 22:54:39 +00:00
|
|
|
parser = argparse.ArgumentParser(prog='mutmuttest.py',
|
2023-12-09 19:52:07 +00:00
|
|
|
description='Runs MutPy over generated test suite.')
|
|
|
|
parser.add_argument('file', type=str, help="Source file to test",
|
|
|
|
nargs="*")
|
|
|
|
|
|
|
|
files = parser.parse_args().file
|
|
|
|
if len(files) == 0:
|
2023-12-18 14:13:31 +00:00
|
|
|
files = [os.path.splitext(f) for f in os.listdir(IN_SOURCE_DIR)]
|
|
|
|
to_test = [file[0] for file in files if file[1] == ".py"]
|
2023-12-09 19:52:07 +00:00
|
|
|
else:
|
|
|
|
to_test = [os.path.splitext(os.path.basename(file))[0] for file in files]
|
|
|
|
|
2023-12-22 16:23:43 +00:00
|
|
|
scores: List[Dict[str, any]] = []
|
|
|
|
|
|
|
|
to_test = [e for t in to_test for e in ([t] * REPS)]
|
|
|
|
|
|
|
|
for filename in tqdm(to_test, desc="Running mut.py over test suite"):
|
|
|
|
source_path = os.path.join(IN_SOURCE_DIR, f"{filename}.py")
|
|
|
|
test_path = os.path.join(IN_TEST_DIR, f"test_{filename}.py")
|
|
|
|
scores.append({
|
|
|
|
'file': filename,
|
|
|
|
'score': run_mutpy(test_path, source_path)
|
|
|
|
})
|
|
|
|
|
|
|
|
df = pd.DataFrame.from_records(scores)
|
|
|
|
df.to_csv(os.path.join(OUT_DIR, 'mutation_results.csv'))
|
2023-12-09 19:52:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|