Тестирование игры (PHPUnit)
У игры на JumPHP могут быть тесты PHPUnit: подсчёт очков, столкновения, ИИ, загрузка уровня… и прежде всего тесты, которые играют в игру («ракетка идёт сверху вниз»), за игрой которых можно наблюдать. Playground запускает их на опубликованной версии, в песочнице, и показывает результат в Студии, тест за тестом, с видеозаписью каждого игрового теста.
Когда Claude разрабатывает вашу игру, он пишет эти тесты по ходу дела: у каждой механики (перемещение, прыжок, выстрел, бонус, враг, конец уровня) есть свой тест, который её проигрывает и запускается после каждого изменения. Вы видите, как они играют в реальном времени, в панели JumPHP, а затем пересматриваете их записанными в Студии после каждой публикации.
Написать тест
В папке игры — папка tests/ с классами …Test.php (PHPUnit 11):
<?php
// tests/ScoreTest.php
namespace Tests;
use App\Entity\Score;
use PHPUnit\Framework\TestCase;
final class ScoreTest extends TestCase
{
public function testABrickIsWorthTenPoints(): void
{
$score = new Score();
$score->brick();
self::assertSame(10, $score->points());
}
}
Код игры загружается так же, как в самой игре (пространства имён из её composer.json, App\ → src/), с движком JumPHP её версии. Tests\ → tests/. На вашем компьютере bin/jumphp test <игра> тоже запускает их (вместе с остальными проверками).
Тесты, которые играют в игру
Игровой тест проигрывает игру кадр за кадром, а затем проверяет, что произошло: «ракетка идёт сверху вниз», «мяч отскакивает», «прыжок приземляется на платформу». Он наследует JumPHP\Testing\GameTestCase:
<?php
namespace Tests;
use App\Entity\Paddle;
use App\Scene\PlayScene;
use JumPHP\Testing\GameTestCase;
final class PaddleTest extends GameTestCase
{
public function testThePaddleGoesFromTheTopToTheBottom(): void
{
$this->game->start(PlayScene::class, ['mode' => 'local']); // сцена, сразу
$paddle = $this->game->peek('left'); // поле сцены, даже приватное
$this->game->hold('p1_up', 60); // клавиша зажата 60 кадров (1 с)
self::assertEqualsWithDelta(PlayScene::TOP, $paddle->getBoundingBox()['y'], 1);
$this->game->hold('p1_down', 90);
self::assertEqualsWithDelta(PlayScene::BOTTOM - Paddle::HEIGHT, $paddle->getBoundingBox()['y'], 1);
}
}
Также: press($action), run($images), wait($secondes), scene(), shot($nom) (скриншот). Называйте тесты предложениями (testTheBallBouncesOnThePaddle): они отображаются именно так («The ball bounces on the paddle»).
За ними можно наблюдать везде:
- на вашем компьютере:
bin/jumphp test <игра>запускает их, а панель JumPHP для Claude Code показывает каждый тест в реальном времени (на скорости игры), а затем его последний кадр; - на сайте: песочница playground проигрывает их без окна и снимает каждый тест на плёнку (один кадр из каждых 4 кадров игры). Страница тестов в Студии показывает их во время выполнения, а затем воспроизводит по кругу: ▶ / ⏸, ползунок, чтобы идти кадр за кадром, щелчок, чтобы открыть кадр крупно.
Этим тестам нужен JumPHP\Testing (JumPHP 0.2.1 или новее): игра на 0.2.0 тестируется на сайте с самым свежим движком, и вывод об этом сообщает. На вашем компьютере bin/jumphp update обновляет JumPHP.
Запуск
- Студия → ваш проект → Тесты (PHPUnit) → «▶ Запустить тесты»: страница обновляется сама (записи игровых тестов появляются во время их выполнения), затем показывает каждый тест (✔ / ✘ и сообщение об ошибке), запись каждого игрового теста и полный вывод PHPUnit.
- Ваш Claude:
run_tests, затемget_test_run(MCP-сервер), например после каждогоsync_project.
Песочница
Тесты выполняются на сервере playground в изоляции: PHP 8.5 (как движок в браузере), PHPUnit 11, без сети, от пользователя без прав, не более 120 секунд и 256 МБ, без окна и звука (SDL работает «вхолостую»: игровые тесты всё равно рисуют каждый кадр для записи). Приватных файлов игры там нет. Результаты и записи видит только владелец игры (хранятся результаты 5 последних запусков).