Добавили тестов. но они пока нерабочие все

This commit is contained in:
ki.sagidullin
2026-04-07 09:12:09 +05:00
parent 5d2b665fa6
commit 18813a3ccb
3 changed files with 495 additions and 0 deletions

1
tests/__init__.py Normal file
View File

@@ -0,0 +1 @@
# Тесты для проекта модульности конфигурации

140
tests/test_config.py Normal file
View File

@@ -0,0 +1,140 @@
"""
test_config.py - Тесты для конфигурации
Проверяют корректность чтения и структуры config.py
"""
import pytest
from config import YEAR, MONTH, SHIFTS, OPERATORS, OPERATOR_PREFERENCES
class TestConfigConstants:
"""Тесты для констант конфигурации"""
def test_year_is_int(self):
"""Год должен быть целым числом"""
assert isinstance(YEAR, int)
assert YEAR == 2026
def test_month_is_int(self):
"""Месяц должен быть целым числом"""
assert isinstance(MONTH, int)
assert MONTH == 4
def test_month_in_range(self):
"""Месяц должен быть в диапазоне 1-12"""
assert 1 <= MONTH <= 12
def test_shifts_is_list(self):
"""Смены должны быть списком"""
assert isinstance(SHIFTS, list)
assert len(SHIFTS) == 4
def test_shifts_structure(self):
"""Каждая смена должна быть кортежем из двух чисел"""
for shift in SHIFTS:
assert isinstance(shift, tuple)
assert len(shift) == 2
start, end = shift
assert isinstance(start, (int, float))
assert isinstance(end, (int, float))
assert start < end
def test_operators_is_list(self):
"""Операторы должны быть списком"""
assert isinstance(OPERATORS, list)
assert len(OPERATORS) > 0
def test_operators_not_empty(self):
"""Список операторов не должен быть пустым"""
assert len(OPERATORS) >= 1
def test_operators_strings(self):
"""Все операторы должны быть строками"""
for op in OPERATORS:
assert isinstance(op, str)
assert len(op) > 0
def test_operator_preferences_structure(self):
"""Структура предпочтений должна быть корректной"""
assert isinstance(OPERATOR_PREFERENCES, dict)
assert len(OPERATOR_PREFERENCES) == len(OPERATORS)
def test_operator_preferences_values(self):
"""Значения предпочтений должны быть словарями"""
for op, prefs in OPERATOR_PREFERENCES.items():
assert isinstance(prefs, dict)
# Проверка, что ключи предпочтений корректны
valid_keys = {'dates', 'day_of_week', 'shift', 'off_dates'}
assert set(prefs.keys()).issubset(valid_keys)
class TestConfigDates:
"""Тесты для дат"""
def test_year_is_positive(self):
"""Год должен быть положительным"""
assert YEAR > 0
def test_month_is_valid(self):
"""Месяц должен быть валидным (1-12)"""
assert 1 <= MONTH <= 12
def test_shifts_time_valid(self):
"""Время смены должно быть валидным (0-24)"""
for start, end in SHIFTS:
assert 0 <= start <= 24
assert 0 <= end <= 24
assert start < end
class TestConfigOperators:
"""Тесты для операторов"""
def test_operators_unique(self):
"""Имена операторов должны быть уникальными"""
assert len(OPERATORS) == len(set(OPERATORS))
def test_operators_no_empty_strings(self):
"""Имена операторов не должны быть пустыми строками"""
for op in OPERATORS:
assert op.strip() != ""
def test_operators_no_special_chars(self):
"""Имена операторов не должны содержать специальные символы"""
for op in OPERATORS:
assert not any(c in op for c in ['<', '>', '/', '\\', '|', ':', '*', '?', '"'])
class TestConfigPreferences:
"""Тесты для предпочтений операторов"""
def test_all_operators_have_preferences(self):
"""Все операторы должны иметь предпочтения"""
assert len(OPERATOR_PREFERENCES) == len(OPERATORS)
def test_dates_in_range(self):
"""Дни в предпочтениях должны быть в диапазоне 1-31"""
for prefs in OPERATOR_PREFERENCES.values():
if 'dates' in prefs:
for day in prefs['dates']:
assert 1 <= day <= 31
def test_shift_in_range(self):
"""Смена в предпочтениях должна быть в диапазоне 0-3"""
for prefs in OPERATOR_PREFERENCES.values():
if 'shift' in prefs:
assert 0 <= prefs['shift'] <= 3
def test_day_of_week_valid(self):
"""День недели в предпочтениях должен быть валидным"""
for prefs in OPERATOR_PREFERENCES.values():
if 'day_of_week' in prefs:
day_str = prefs['day_of_week']
# Проверяем, что это строка с валидным значением
assert day_str.lower() in ['понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота', 'воскресенье']
def test_off_dates_in_range(self):
"""Дни отдыха должны быть в диапазоне 1-31"""
for prefs in OPERATOR_PREFERENCES.values():
if 'off_dates' in prefs:
for day in prefs['off_dates']:
assert 1 <= day <= 31

354
tests/test_models.py Normal file
View File

@@ -0,0 +1,354 @@
"""
test_models.py - Тесты для моделей и предпочтений
Проверяют корректность работы класса OperatorPreferences и связанных функций
"""
import pytest
from datetime import datetime
from models import (
OperatorPreferences,
PreferencesBuilder,
DayOfWeek,
PreferenceType,
get_days,
create_model,
solve_model,
get_solution
)
from config import YEAR, MONTH, SHIFTS, OPERATORS
class TestDayOfWeek:
"""Тесты для enum DayOfWeek"""
def test_day_of_week_values(self):
"""Проверка значений enum"""
assert DayOfWeek.MONDAY.value == 0
assert DayOfWeek.TUESDAY.value == 1
assert DayOfWeek.WEDNESDAY.value == 2
assert DayOfWeek.THURSDAY.value == 3
assert DayOfWeek.FRIDAY.value == 4
assert DayOfWeek.SATURDAY.value == 5
assert DayOfWeek.SUNDAY.value == 6
def test_day_of_week_names(self):
"""Проверка названий enum"""
assert DayOfWeek.MONDAY.name == "MONDAY"
assert DayOfWeek.SUNDAY.name == "SUNDAY"
class TestOperatorPreferences:
"""Тесты для класса OperatorPreferences"""
def test_creation(self):
"""Тест создания объекта предпочтений"""
prefs = OperatorPreferences("Тестовый")
assert prefs.operator_name == "Тестовый"
assert prefs.work_on_dates == []
assert prefs.work_on_day_of_week == []
assert prefs.work_only_shift is None
assert prefs.off_on_dates == []
def test_to_dict_empty(self):
"""Тест конвертации в словарь для пустых предпочтений"""
prefs = OperatorPreferences("Тестовый")
result = prefs.to_dict()
assert result == {}
def test_to_dict_with_dates(self):
"""Тест конвертации с датами"""
prefs = OperatorPreferences("Тестовый")
prefs.work_on_dates = [10, 15, 20]
result = prefs.to_dict()
assert result['dates'] == [10, 15, 20]
def test_to_dict_with_shift(self):
"""Тест конвертации со сменой"""
prefs = OperatorPreferences("Тестовый")
prefs.work_only_shift = 2
result = prefs.to_dict()
assert result['shift'] == 2
def test_to_dict_with_day_of_week(self):
"""Тест конвертации с днем недели"""
prefs = OperatorPreferences("Тестовый")
prefs.work_on_day_of_week = [DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY]
result = prefs.to_dict()
assert result['day_of_week'] == ['monday', 'wednesday']
def test_to_dict_with_off_dates(self):
"""Тест конвертации с днями отдыха"""
prefs = OperatorPreferences("Тестовый")
prefs.off_on_dates = [5, 12, 19]
result = prefs.to_dict()
assert result['off_dates'] == [5, 12, 19]
def test_to_dict_all(self):
"""Тест конвертации всех полей"""
prefs = OperatorPreferences("Тестовый")
prefs.work_on_dates = [10, 15]
prefs.work_on_day_of_week = [DayOfWeek.MONDAY]
prefs.work_only_shift = 1
prefs.off_on_dates = [5]
result = prefs.to_dict()
assert result['dates'] == [10, 15]
assert result['day_of_week'] == ['monday']
assert result['shift'] == 1
assert result['off_dates'] == [5]
def test_from_dict(self):
"""Тест создания из словаря"""
data = {
'dates': [10, 15],
'day_of_week': ['monday'],
'shift': 1,
'off_dates': [5]
}
prefs = OperatorPreferences.from_dict("Тестовый", data)
assert prefs.work_on_dates == [10, 15]
assert prefs.work_on_day_of_week == [DayOfWeek.MONDAY]
assert prefs.work_only_shift == 1
assert prefs.off_on_dates == [5]
def test_from_dict_partial(self):
"""Тест создания из словаря с неполными данными"""
data = {'dates': [10]}
prefs = OperatorPreferences.from_dict("Тестовый", data)
assert prefs.work_on_dates == [10]
assert prefs.work_on_day_of_week == []
assert prefs.work_only_shift is None
assert prefs.off_on_dates == []
def test_from_dict_invalid_day_of_week(self):
"""Тест обработки невалидного дня недели"""
data = {'day_of_week': ['invalid']}
prefs = OperatorPreferences.from_dict("Тестовый", data)
assert prefs.work_on_day_of_week == []
def test_from_dict_invalid_shift(self):
"""Тест обработки невалидной смены"""
data = {'shift': 5}
prefs = OperatorPreferences.from_dict("Тестовый", data)
assert prefs.work_only_shift is None
def test_from_dict_invalid_dates(self):
"""Тест обработки невалидных дат"""
data = {'dates': [32]}
prefs = OperatorPreferences.from_dict("Тестовый", data)
assert prefs.work_on_dates == []
def test_from_dict_invalid_off_dates(self):
"""Тест обработки невалидных дней отдыха"""
data = {'off_dates': [32]}
prefs = OperatorPreferences.from_dict("Тестовый", data)
assert prefs.off_on_dates == []
class TestPreferencesBuilder:
"""Тесты для класса PreferencesBuilder"""
def test_creation(self):
"""Тест создания объекта"""
builder = PreferencesBuilder("Тестовый")
assert builder.operator_name == "Тестовый"
assert builder._preferences is None
def test_add_dates(self):
"""Тест добавления дат"""
builder = PreferencesBuilder("Тестовый")
builder.add_dates([10, 15])
assert builder._preferences.work_on_dates == [10, 15]
def test_add_day_of_week(self):
"""Тест добавления дней недели"""
builder = PreferencesBuilder("Тестовый")
builder.add_day_of_week([DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY])
assert len(builder._preferences.work_on_day_of_week) == 2
def test_add_shift(self):
"""Тест добавления смены"""
builder = PreferencesBuilder("Тестовый")
builder.add_shift(2)
assert builder._preferences.work_only_shift == 2
def test_add_off_dates(self):
"""Тест добавления дней отдыха"""
builder = PreferencesBuilder("Тестовый")
builder.add_off_dates([5, 12])
assert builder._preferences.off_on_dates == [5, 12]
def test_to_dict(self):
"""Тест конвертации в словарь"""
builder = PreferencesBuilder("Тестовый")
builder.add_dates([10])
builder.add_shift(1)
result = builder.to_dict()
assert result['dates'] == [10]
assert result['shift'] == 1
def test_to_dict_empty(self):
"""Тест конвертации пустых предпочтений"""
builder = PreferencesBuilder("Тестовый")
result = builder.to_dict()
assert result == {}
def test_to_dict_invalid(self):
"""Тест обработки невалидных данных"""
builder = PreferencesBuilder("Тестовый")
builder.add_dates([32]) # Невалидная дата
result = builder.to_dict()
assert result == {}
def test_to_dict_invalid_day_of_week(self):
"""Тест обработки невалидного дня недели"""
builder = PreferencesBuilder("Тестовый")
builder.add_day_of_week([DayOfWeek.MONDAY, "invalid"])
result = builder.to_dict()
assert result['day_of_week'] == ['monday']
def test_to_dict_invalid_shift(self):
"""Тест обработки невалидной смены"""
builder = PreferencesBuilder("Тестовый")
builder.add_shift(5) # Невалидная смена
result = builder.to_dict()
assert result == {}
def test_to_dict_invalid_off_dates(self):
"""Тест обработки невалидных дней отдыха"""
builder = PreferencesBuilder("Тестовый")
builder.add_off_dates([32]) # Невалидная дата
result = builder.to_dict()
assert result == {}
class TestGetDays:
"""Тесты для функции get_days"""
def test_days_count(self):
"""Проверка количества дней"""
days = get_days()
assert len(days) == 30 # Апрель 2026
def test_days_format(self):
"""Проверка формата дней"""
days = get_days()
for day in days:
assert isinstance(day, str)
assert len(day) == 10 # YYYY-MM-DD
assert '-' in day
def test_days_sorted(self):
"""Проверка сортировки дней"""
days = get_days()
assert days == sorted(days)
def test_days_start(self):
"""Проверка первого дня"""
days = get_days()
assert days[0] == "2026-04-01"
def test_days_end(self):
"""Проверка последнего дня"""
days = get_days()
assert days[-1] == "2026-04-30"
class TestCreateModel:
"""Тесты для функции create_model"""
def test_model_creation(self):
"""Тест создания модели"""
model, variables, operators_set = create_model()
assert model is not None
assert variables is not None
assert operators_set is not None
assert len(operators_set) == len(OPERATORS)
def test_variables_count(self):
"""Тест количества переменных"""
model, variables, operators_set = create_model()
expected_count = len(get_days()) * len(SHIFTS) * len(OPERATORS)
assert len(variables) == expected_count
def test_operators_set(self):
"""Тест множества операторов"""
model, variables, operators_set = create_model()
assert operators_set == set(OPERATORS)
def test_model_has_constraints(self):
"""Тест наличия ограничений"""
model, variables, operators_set = create_model()
# Модель должна иметь ограничения
assert model.NumConstraints() > 0
def test_model_has_hints(self):
"""Тест наличия подсказок"""
model, variables, operators_set = create_model()
# Модель должна иметь подсказки
assert model.NumHints() > 0
class TestSolveModel:
"""Тесты для функции solve_model"""
def test_solve_returns_bool(self):
"""Тест возврата булевого значения"""
result = solve_model()
assert isinstance(result, bool)
def test_solve_with_valid_config(self):
"""Тест решения с валидной конфигурацией"""
# Это может занять время, поэтому тестуем только факт вызова
try:
result = solve_model()
# Результат может быть True или False в зависимости от конфигурации
assert isinstance(result, bool)
except Exception as e:
pytest.fail(f"Ошибка при решении модели: {e}")
class TestGetSolution:
"""Тесты для функции get_solution"""
def test_solution_structure(self):
"""Тест структуры решения"""
schedule = get_solution()
assert isinstance(schedule, dict)
assert len(schedule) > 0
def test_solution_days(self):
"""Тест дней в решении"""
schedule = get_solution()
days = get_days()
assert set(schedule.keys()) == set(days)
def test_solution_shifts(self):
"""Тест смен в решении"""
schedule = get_solution()
for day, day_shifts in schedule.items():
assert isinstance(day_shifts, dict)
assert len(day_shifts) == len(SHIFTS)
def test_solution_operators(self):
"""Тест операторов в решении"""
schedule = get_solution()
for day, day_shifts in schedule.items():
for shift_idx, shift_data in day_shifts.items():
assert isinstance(shift_data, dict)
assert len(shift_data) == len(OPERATORS)
def test_solution_values(self):
"""Тест значений в решении"""
schedule = get_solution()
for day, day_shifts in schedule.items():
for shift_idx, shift_data in day_shifts.items():
for op_name, value in shift_data.items():
assert isinstance(value, bool)
assert value in [True, False]
def test_solution_consistency(self):
"""Тест согласованности решения"""
schedule = get_solution()
# Каждый день и смена должны иметь ровно одного оператора
for day, day_shifts in schedule.items():
for shift_idx, shift_data in day_shifts.items():
active_operators = [op for op, value in shift_data.items() if value]
assert len(active_operators) == 1