emeset/test

Eines de testing per a projectes basats en el microframework docent Emeset.

Installs: 28

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/emeset/test

0.1.11 2025-12-11 11:58 UTC

This package is auto-updated.

Last update: 2025-12-11 11:59:37 UTC


README

Eines de testing per a projectes basats en el microframework docent Emeset.

L’objectiu del paquet és que, en un projecte Emeset, puguis escriure tests així de senzills:

use Emeset\Test\TestCase;

class ExempleTest extends TestCase
{
    public function test_exemple()
    {
        $request  = $this->makeRequest($get, $post, $session);
        $response = $this->makeResponse();

        // ...
    }
}

i tenir automàticament disponible:

  • el contenidor d’Emeset (App\Container o Emeset\Container),
  • el fitxer de configuració del projecte (App/config.php),
  • l’entorn de test (.env.test),
  • una sessió PHP inicialitzada per treballar amb $_SESSION i middleware.

Instal·lació

Al teu projecte Emeset (per exemple, el projecte links o el projecte de sessió/login), executa:

composer require --dev emeset/test

Això instal·larà:

  • el paquet emeset/test,
  • el framework emeset/framework (si no el tens ja),
  • i phpunit/phpunit.

Configuració bàsica del projecte

El paquet NO crea fitxers al teu projecte ni genera res automàticament.
Tu decideixes on van les coses. Et proposo la següent estructura:

.
├─ App/
├─ public/
├─ vendor/
├─ tests/
│  ├─ bootstrap.php
│  └─ ... 
└─ phpunit.xml

1. Fitxer phpunit.xml a l’arrel del projecte

Crea un fitxer phpunit.xml amb aquest contingut mínim:

<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
         bootstrap="tests/bootstrap.php"
         cacheDirectory=".phpunit.cache"
         executionOrder="depends,defects"
         beStrictAboutCoverageMetadata="true"
         beStrictAboutOutputDuringTests="true"
         displayDetailsOnPhpunitDeprecations="true"
         failOnPhpunitDeprecation="true">
    <testsuites>
        <testsuite name="default">
            <directory>tests</directory>
        </testsuite>
    </testsuites>

    <source ignoreIndirectDeprecations="true" restrictNotices="true" restrictWarnings="true">
        <include>
            <directory>App/</directory>
        </include>
    </source>
</phpunit>

2. Fitxer tests/bootstrap.php

Crea el fitxer tests/bootstrap.php:

<?php

// Carrega l'autoload de Composer (Emeset, el teu projecte, etc.)
require __DIR__ . '/../vendor/autoload.php';

// Marquem explícitament que estem en mode test
putenv('PHPUNIT_RUNNING=1');

// Zona horària per evitar avisos
date_default_timezone_set('Europe/Madrid');

3. Afegir un script de test a composer.json (opcional però recomanat)

Al composer.json del teu projecte pots afegir:

"scripts": {
    "test": "phpunit --testdox --colors=always"
}

A partir d’ara, podràs executar els tests amb:

composer test

Escriure el primer test (SmokeTest)

Crea la carpeta tests/ i dins un fitxer tests/SmokeTest.php:

<?php

use PHPUnit\Framework\TestCase;

class SmokeTest extends TestCase
{
    public function test_phpunit_funciona()
    {
        $this->assertTrue(true);
    }
}

Executa:

composer test

Si tot està bé, veuràs que tens 1 test OK.
A partir d’aquí ja pots fer servir la Emeset\Test\TestCase per provar el teu codi Emeset.

Classe base Emeset\Test\TestCase

Quan vulguis fer tests del teu codi Emeset (controladors, middlewares, models…), fes servir la classe base del paquet:

<?php

namespace Tests\Controllers;

use Emeset\Test\TestCase;
use App\Controllers\Portada;

class PortadaControllerTest extends TestCase
{
    public function test_index()
    {
        $request  = $this->makeRequest($get, $post, $session);
        $response = $this->makeResponse();

        $controller = new Portada();
        $response = $controller->index($request, $response, $this->container);

        // Asserts aquí...
    }
}

Què fa aquesta TestCase per tu?

A cada test:

  • Crea el contenidor del projecte (App\Container si existeix, sinó Emeset\Container).
  • Carrega el fitxer de configuració del projecte (App/config.php).
  • Marca l’entorn com a test (PHPUNIT_RUNNING=1) perquè Emeset pugui carregar .env.test.
  • Assegura que la sessió està engegada (session_start() si cal) i neteja $_SESSION abans de cada test.
  • Et proporciona aquests helpers:
$this->container   // Contenidor del projecte
$this->makeRequest($get, $post, $session)  // Obté una Request del contenidor passem un array per get, post i ssession per inicialitzar els valors.
$this->makeResponse() // Obté una Response del contenidor

Recursos d’exemple al paquet

Dins el paquet emeset/test trobaràs una carpeta resources/ amb exemples:

resources/
├─ phpunit.xml.dist
└─ tests/
   ├─ ExampleSmokeTest.php
   ├─ ExamplePortadaControllerTest.php
   └─ ExampleAuthMiddlewareTest.php

ExamplePortadaControllerTest.php (resum)

Exemple de test d’un controlador que carrega una vista:

<?php

use Emeset\Test\TestCase;
use App\Controllers\Portada;
use Emeset\Views\ViewsPHP;

class ExamplePortadaControllerTest extends TestCase
{
    public function test_index_carrega_la_plantilla_portada()
    {
        $request  = $this->makeRequest();
        $response = $this->makeResponse();

        $controller = new Portada();
        $response   = $controller->index($request, $response, $this->container);

        $view = $response->getView();

        $this->assertSame('portada.php', $view->getTemplate());
    }
}

ExamplePortadaRutaTest.php (resum)

Exemple de test d’una ruta:

Emeset/test també permet fer testos de rutes, aquest són testos d'integració. Per poder-ho fer cal fer un petit canvi a l'index.php Caldrà copiar les rutes a un fitxer rutes.php que crearem a la carpeta App/. Així a l'index.php passarem de:

$app = new \Emeset\Emeset($contenidor);
$app->middleware([\App\Middleware\App::class, "execute"]);

/* Definim les rutes de la nostra aplicació */
$app->get("", [\App\Controllers\Portada::class, "index"]);
$app->get("login",  [\App\Controllers\Login::class, "login"]);
$app->post("validar-login", [\App\Controllers\Login::class, "validarLogin"]);
$app->get("privat", [\App\Controllers\Privat::class, "privat"], ["auth"]);
$app->get("tancar-sessio", [\App\Controllers\Login::class, "tancarSessio"], ["auth"]);

$app->get("ajax", function ($request, $response) {
    $response->set("result", "ok");
    return $response;
});

$app->get("/hola/{id}", function ($request, $response) {
    $id = $request->getParam("id");
    $response->setBody("Hola {$id}!");
    return $response;
});


$app->route(\Emeset\Router::DEFAULT_ROUTE, "ctrlError");

$app->execute();

a

$app = new \Emeset\Emeset($contenidor);
require __DIR__ . '/../App/routes.php';
$app->execute();

I al fitxer App\routes.php

<?php

$app->middleware([\App\Middleware\App::class, "execute"]);

/* Definim les rutes de la nostra aplicació */
$app->get("", [\App\Controllers\Portada::class, "index"]);
$app->get("login",  [\App\Controllers\Login::class, "login"]);
$app->post("validar-login", [\App\Controllers\Login::class, "validarLogin"]);
$app->get("privat", [\App\Controllers\Privat::class, "privat"], ["auth"]);
$app->get("tancar-sessio", [\App\Controllers\Login::class, "tancarSessio"], ["auth"]);

$app->get("ajax", function ($request, $response) {
    $response->set("result", "ok");
    return $response;
});

$app->get("/hola/{id}", function ($request, $response) {
    $id = $request->getParam("id");
    $response->setBody("Hola {$id}!");
    return $response;
});


$app->route(\Emeset\Router::DEFAULT_ROUTE, "ctrlError");

Aquest canvi permetra que el testCase també pugui inicialtizar les rutes per als testos.

I podrem fer testos com aquest.

<?php

use Emeset\Test\TestCase;
use App\Controllers\Portada;
use Emeset\Views\ViewsPHP;

class ExamplePortadaControllerTest extends TestCase
{
    public function test_index_carrega_la_plantilla_portada()
    {
        $request  = $this->makeRequest();
        $response = $this->makeResponse();

        $this->get('/', [], $session);

        $view = $response->getView();

        $this->assertSame('portada.php', $view->getTemplate());
    }
}

El test case té tres mètodes per fer testos de rutes:

  • protected function get(string $uri, array $query = [], array $session = [])
  • protected function post(string $uri, array $post = [], array $session = [])
  • protected function call(string $method, string $uri, array $query = [], array $post = [], array $session = []): \Emeset\Contracts\Http\Response

Flux de treball recomanat

  1. Instal·lar el paquet al projecte Emeset:

    composer require --dev emeset/test
  2. Crear phpunit.xml i tests/bootstrap.php a partir de les plantilles.

  3. Afegir un primer SmokeTest senzill.

  4. Crear un test de controlador que no toqui base de dades (per exemple, Portada).

  5. Quan això funcioni, passar al tutorial de FirstStepsUnitTesting.md per provar controladors que sí que treballen amb BD.

On seguir

  • FirstStepsUnitTesting.md → guia pas a pas per crear un test d’un controlador que interactua amb la base de dades.