Первый автоматизированный тест
Расширьте исполняемые проверки из трёх слоёв в примере Minimal Multiplayer.
Слои тестирования
RunTutorialChecks запускает по порядку следующие слои:
- Проверка запечённых метаданных.
run_tutorial_smoke.pyдекодирует серверные и клиентские метаданные, требует симметричных объявлений remote call и подтверждает присутствиеSuppliesCollectedна обеих сторонах. - Серверный тест контента. Sub-config
TutorialContentTestзапускает изолированный сервер с базой данных в памяти и отключённой сетью. Проверки скрипта создают локацию и карту, добавляют NPC и предмет и проверяют инварианты карты. - Smoke-тест видимого клиенту поведения. Headless-клиент подключается к настоящему слушающему серверу, входит в игру, загружает карту, подбирает предмет, наблюдает синхронизированный счётчик и запрашивает штатное завершение.
Headless-клиент подтверждает подключение, запекание, загрузку карты, локализацию, remote call и репликацию. Он не проверяет пиксели, удобство ввода, звук или работу GPU; для таких утверждений сохраняйте визуальную проверку.
Запустите все слои
Из корня отдельного checkout примера:
cmake --preset windows
cmake --build --preset windows-check
В Linux используйте linux и linux-check. Команда python validate.py
выбирает подходящие команды для текущего хоста.
CI движка использует эквивалентный переиспользуемый маршрут:
cd Examples\MinimalMultiplayer
python validate.py
Добавьте одно условие контента
Предположим, проект добавляет предмет со стабильным именем TutorialBeacon.
Сначала добавьте его прототип, затем расширьте RunContentTest() в
Scripts/Tutorial.fos:
const hstring BeaconPid = "TutorialBeacon".hstr();
void RunContentTest()
{
verify(Game.CheckProtoItem(BeaconPid), "Tutorial beacon prototype is missing");
// Keep the existing assertions and clean shutdown.
}
Разместите константу рядом с другими стабильными идентификаторами и сохраните существующее тело функции; сокращённый пример выше показывает только новую проверку. Запустите полный маршрут. Затем временно внесите опечатку в идентификатор и убедитесь, что слой тестирования контента завершается ошибкой до запуска многопользовательского клиента. Восстановите корректный идентификатор и повторите проверку.
Такое воспроизведение ошибки с последующим успешным запуском доказывает, что проверка активна. Тест, который наблюдали только зелёным, даёт более слабое свидетельство.
Политика маркеров и таймаутов
Маркеры образуют небольшой публичный контракт между скриптами примера и runner:
- используйте стабильные имена в нижнем регистре, удобные для машинного поиска;
- выводите маркер только после появления проверенного состояния;
- требуйте нулевой код завершения процесса и каждый маркер;
- ограничивайте время ожидания каждого процесса;
- при ошибке завершайте оба процесса;
- помечайте захваченный вывод сервера и клиента и отклоняйте результат при отсутствии любого маркера.
Не заменяйте проверки состояния проверками журнала. Скриптовый verify(...)
проверяет инвариант мира; маркер сообщает внешнему runner, какой проверенный
этап завершён.
Граница постоянного хранения
SuppliesCollected и TutorialAccount объявлены как Persistent, а проверка
запечённых метаданных защищает эти объявления. Руководство использует
Server.DbStorage = Memory, поэтому не заявляет о сохранении данных между
перезапусками серверного процесса. Игра, заявляющая такое сохранение, должна
выполнять дополнительный тест с поддерживаемым backend базы данных и проверять
восстановленное состояние сущностей.
Восстановление после ошибок
- Метаданные не проходят проверку до запуска: сравните обе запечённые стороны и сигнатуры remote call; не ослабляйте декодер.
- Клиент подключается, но не загружает карту: проверьте создание мира на сервере и переключение игрока и криттера, прежде чем увеличивать задержки.
- Тест нестабилен: ожидайте семантические этапы с ограниченным таймаутом; не используйте фиксированные задержки как критерий успеха.
Переиспользуемая семантика fixture, маркеров, таймаутов, очистки и отчётов о процессах описана в Тестировании игрового процесса и интеграций. Владение нативными тестами Catch2 и покрытием описано в Тестировании.