rusi/test_ru/run_tests.py

187 lines
6 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""
run_tests.py - Запуск русских тестов для rusi
"""
import os
import sys
import csv
import subprocess
from pathlib import Path
RUSI = "./rusi.elf"
TEST_DIR = Path(__file__).parent
GREEN = "\033[92m"
RED = "\033[91m"
YELLOW = "\033[93m"
BLUE = "\033[94m"
RESET = "\033[0m"
BOLD = "\033[1m"
def print_header(text):
print(f"\n{BOLD}{BLUE}{'='*60}{RESET}")
print(f"{BOLD}{BLUE}{text:^60}{RESET}")
print(f"{BOLD}{BLUE}{'='*60}{RESET}")
def load_tests():
csv_file = TEST_DIR / "test_ru.csv"
tests = []
if not csv_file.exists():
for f in sorted(TEST_DIR.glob("*.c")):
tests.append({
"номер": f.stem.split('_')[0] if '_' in f.stem else "??",
"тест": f.stem,
"описание": "Без описания",
"ожидаемый_код": None,
"файл": f
})
return tests
with open(csv_file, 'r', encoding='utf-8-sig') as f:
reader = csv.DictReader(f)
for row in reader:
test_name = row['Тест'].strip()
test_file = TEST_DIR / f"{test_name}.c"
if test_file.exists():
try:
expected = int(str(row['Ожидаемый_код']).strip())
except (ValueError, KeyError):
expected = None
tests.append({
"номер": row['Номер'].strip(),
"тест": test_name,
"описание": row['Описание'].strip(),
"ожидаемый_код": expected,
"файл": test_file
})
return tests
def compile_test(test_name, test_file):
exe_file = TEST_DIR / test_name
if not os.path.exists(RUSI):
return False, f"rusi не найден: {RUSI}"
cmd = [RUSI, "-o", str(exe_file), str(test_file)]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
return False, result.stderr
return True, str(exe_file)
def run_test(exe_file):
result = subprocess.run([exe_file], capture_output=True, text=True)
return result.returncode, result.stdout, result.stderr
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--keep", "-k", action="store_true")
parser.add_argument("--verbose", "-v", action="store_true")
parser.add_argument("--test", "-t")
args = parser.parse_args()
print_header("ЗАПУСК РУССКИХ ТЕСТОВ ДЛЯ RUSI")
tests = load_tests()
if args.test:
tests = [t for t in tests if t["тест"] == args.test or t["номер"] == args.test]
if not tests:
print(f"{RED}ОШИБКА: Тест '{args.test}' не найден{RESET}")
sys.exit(1)
if not tests:
print(f"{YELLOW}ВНИМАНИЕ: Тесты не найдены{RESET}")
sys.exit(0)
print(f"\nНайдено тестов: {len(tests)}")
print(f"Компилятор: {RUSI}")
print(f"Папка тестов: {TEST_DIR}")
print()
passed = 0
failed = 0
results = []
for test in tests:
test_name = test["тест"]
test_file = test["файл"]
expected = test["ожидаемый_код"]
exe_file = TEST_DIR / test_name
ok, result = compile_test(test_name, test_file)
if not ok:
print(f" {RED}{RESET} {test_name:<20} Ошибка компиляции")
if args.verbose:
print(f" {result}")
failed += 1
results.append((test_name, False, "compile_error", None))
continue
code, stdout, stderr = run_test(str(exe_file))
if expected is not None:
if code == expected:
print(f" {GREEN}{RESET} {test_name:<20} ожидалось {expected}, получено {code}")
passed += 1
results.append((test_name, True, "пройден", code))
else:
print(f" {RED}{RESET} {test_name:<20} ожидалось {expected}, получено {code}")
if args.verbose:
if stdout:
print(f" Вывод: {stdout.strip()}")
if stderr:
print(f" Ошибки: {stderr.strip()}")
failed += 1
results.append((test_name, False, f"expected_{expected}_got_{code}", code))
else:
if code == 0:
print(f" {GREEN}{RESET} {test_name:<20} завершился успешно (код {code})")
passed += 1
results.append((test_name, True, "пройден", code))
else:
print(f" {RED}{RESET} {test_name:<20} завершился с ошибкой (код {code})")
failed += 1
results.append((test_name, False, f"failed_with_{code}", code))
if not args.keep and exe_file.exists():
os.remove(exe_file)
print_header("РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ")
for test_name, ok, status, code in results:
if ok:
print(f" {GREEN}{RESET} {test_name:<20} {status}")
else:
print(f" {RED}{RESET} {test_name:<20} {status}")
print(f"\n{BOLD}Итого:{RESET}")
print(f" {GREEN}Пройдено:{RESET} {passed}")
print(f" {RED}Провалено:{RESET} {failed}")
print(f" {BOLD}Всего:{RESET} {len(tests)}")
if args.keep:
print(f"\n{YELLOW}Бинарники сохранены в {TEST_DIR}{RESET}")
if failed > 0:
sys.exit(1)
else:
print(f"\n{GREEN}{BOLD}🎉 Все тесты пройдены!{RESET}")
sys.exit(0)
if __name__ == "__main__":
main()