PT

Testar o seu jogo (PHPUnit)

Um jogo JumPHP pode ter testes PHPUnit: o cálculo da pontuação, as colisões, a IA, o carregamento de uma fase… e sobretudo testes que jogam o jogo (“a raquete vai de cima a baixo”) e que você assiste jogando. O playground os executa na versão publicada, em uma sandbox, e mostra o resultado no Studio, teste por teste, com o filme de cada teste de jogo.

Quando o Claude desenvolve o seu jogo, ele escreve esses testes aos poucos: cada mecânica (um movimento, um pulo, um tiro, um bônus, um inimigo, o fim de uma fase) tem o seu teste que a joga, executado após cada mudança. Você os vê jogando ao vivo no painel JumPHP e depois os revê filmados no Studio após cada publicação.

Escrever um teste

Na pasta do jogo, uma pasta tests/ com classes …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());
    }
}

O código do jogo é carregado como no jogo (os namespaces do composer.json dele, App\ → src/), com o motor JumPHP da versão dele. Tests\ → tests/. No seu computador, bin/jumphp test <jogo> também os executa (junto com o resto das verificações).

Testes que jogam o jogo

Um teste de jogo faz o jogo ser jogado, quadro a quadro, e depois verifica o que aconteceu: “a raquete vai de cima a baixo”, “a bola quica”, “o pulo cai de volta na plataforma”. Ele estende 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']);  // a cena, na hora
        $paddle = $this->game->peek('left');                       // um campo da cena, mesmo privado
        $this->game->hold('p1_up', 60);                            // a tecla segurada por 60 quadros (1 s)
        self::assertEqualsWithDelta(PlayScene::TOP, $paddle->getBoundingBox()['y'], 1);
        $this->game->hold('p1_down', 90);
        self::assertEqualsWithDelta(PlayScene::BOTTOM - Paddle::HEIGHT, $paddle->getBoundingBox()['y'], 1);
    }
}

Também: press($action), run($frames), wait($seconds), scene(), shot($name) (uma captura). Dê aos testes nomes de frases (testTheBallBouncesOnThePaddle): eles são exibidos assim (“The ball bounces on the paddle”).

Você os assiste jogando, em todo lugar:

  • no seu computador: bin/jumphp test <jogo> os executa, e o painel JumPHP do Claude Code mostra cada teste ao vivo (na velocidade do jogo) e depois o último quadro dele;
  • no site: a sandbox do playground os joga sem janela e filma cada teste (um quadro a cada 4 do jogo). A página de testes do Studio os mostra enquanto rodam e depois os reproduz em loop: ▶ / ⏸, um controle deslizante para avançar quadro a quadro, um clique para abrir o quadro em tamanho grande.

Esses testes precisam de JumPHP\Testing (JumPHP 0.2.1 ou superior): um jogo em 0.2.0 é testado no site com o motor mais recente, e a saída avisa isso. No seu computador, bin/jumphp update atualiza o JumPHP.

Executá-los

  • Studio → o seu projeto → Testes (PHPUnit) → “▶ Executar os testes”: a página se atualiza sozinha (os filmes dos testes de jogo aparecem enquanto rodam) e depois mostra cada teste (✔ / ✘ e a mensagem de falha), o filme de cada teste de jogo e a saída completa do PHPUnit.
  • O seu Claude: run_tests e depois get_test_run (servidor MCP), por exemplo após cada sync_project.

A sandbox

Os testes rodam no servidor do playground, isolados: PHP 8.5 (como o motor no navegador), PHPUnit 11, sem rede, sob um usuário sem privilégios, no máximo 120 segundos e 256 MB, sem janela nem som (o SDL roda “em vazio”: os testes de jogo desenham mesmo assim cada quadro, para o filme). Os arquivos privados do jogo não estão lá. Só o proprietário do jogo vê os resultados e os filmes (os das 5 últimas execuções são guardados).