Глава 19 · Архитектура
Тестируем правила игры
Раз правила — чистые функции, их можно проверить обычным assert, без окна и без Xvfb.
Проверяем правила напрямую, без единого окна
Раздел 19.26 показал, что правила игры — чистые функции. Значит, их можно проверить
обычным assert, как в главе 3 — без Xvfb, без
turtle.Screen(), без ожидания, пока что-то нарисуется:
test_snake_logic.py
def test_move_snake_without_growth_drops_tail():
snake = [(0, 0), (-20, 0), (-40, 0)]
result = move_snake(snake, (20, 0), grow=False)
assert result == [(20, 0), (0, 0), (-20, 0)]
def test_wall_collision_boundary_is_safe():
assert is_wall_collision((280, 280)) is False
def test_wall_collision_beyond_boundary():
assert is_wall_collision((300, 0)) is True
Пограничные случаи — отдельные тесты, а не один общий
«Безопасно ровно на границе» и «столкновение чуть дальше границы» — два разных теста, не один: если объединить их в одну проверку, тест может остаться зелёным даже при ошибке ровно в этой точке (раздел 19.19 разбирал, почему граница включена).
Тестировать сценарии, для которых важна случайность (выбор еды), помогает
random.Random(seed) с зафиксированным зерном — раздел 19.18 уже
объяснял, зачем choose_food() принимает готовый генератор, а не
читает глобальный random напрямую:
test_food.py
def test_choose_food_never_lands_on_snake():
rng = random.Random(1)
snake = [(0, 0), (-20, 0), (-40, 0)]
for _ in range(50):
food = choose_food(snake, rng)
assert food not in snake
Практика: пишем тест правила игры
Автоматическая проверка — функция test_boundary_is_safe(): тест обязан поймать сломанную версию