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
Requires
- php: >=8.0
- emeset/framework: ^0.4
- phpunit/phpunit: ^12.0
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\ContaineroEmeset\Container), - el fitxer de configuració del projecte (
App/config.php), - l’entorn de test (
.env.test), - una sessió PHP inicialitzada per treballar amb
$_SESSIONi 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\Containersi 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$_SESSIONabans 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
-
Instal·lar el paquet al projecte Emeset:
composer require --dev emeset/test
-
Crear
phpunit.xmlitests/bootstrap.phpa partir de les plantilles. -
Afegir un primer
SmokeTestsenzill. -
Crear un test de controlador que no toqui base de dades (per exemple, Portada).
-
Quan això funcioni, passar al tutorial de
FirstStepsUnitTesting.mdper 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.