Primeros pasos con Nette Tester

Hasta los buenos programadores cometen errores. La diferencia entre un buen programador y uno malo es que el bueno comete el error una sola vez y la siguiente lo detecta con pruebas automatizadas.

  • “Quien no prueba está condenado a repetir sus errores.” (proverbio)
  • “En cuanto nos deshacemos de un error, aparece otro.” (ley de Murphy)
  • “Siempre que sientas la tentación de escribir un print, escríbelo como prueba.” (Martin Fowler)

¿Ha escrito alguna vez en PHP un código como este?

$obj = new MyClass;
$result = $obj->process($input);

var_dump($result);

Es decir, ¿ha imprimido el resultado de una llamada a una función solo para comprobar visualmente si devuelve lo que debería? Probablemente lo hace muchas veces al día. Con la mano en el corazón: si todo funciona bien, ¿borra ese código? ¿Espera que la clase no se rompa en el futuro? Las leyes de Murphy garantizan lo contrario :-)

En el fondo ha escrito una prueba. Solo hace falta modificarla un poco para que no requiera inspección visual, sino que se compruebe sola. Y si no borra la prueba, podrá ejecutarla en cualquier momento en el futuro para verificar que todo sigue funcionando como debe. Con el tiempo creará un gran número de pruebas así, con lo que convendría ejecutarlas automáticamente.

Y con todo eso le ayudará Nette Tester.

¿Qué hace único a Tester?

Escribir pruebas para Nette Tester es único porque cada prueba es un script PHP normal que se puede ejecutar por sí solo.

Así que, cuando escribe una prueba, puede simplemente ejecutarla y averiguar si contiene, por ejemplo, un error de programación. Si funciona correctamente. Si no, puede recorrerla con facilidad en su IDE y buscar el fallo. Incluso puede abrirla en un navegador.

Y lo más importante: al ejecutarla, ejecuta la prueba. Averigua de inmediato si pasó o falló. ¿Cómo? Vamos a mostrarlo. Escribiremos una prueba trivial del trabajo con un array de PHP y la guardaremos en el archivo ArrayTest.php:

<?php
use Tester\Assert;

require __DIR__ . '/vendor/autoload.php';  # carga el autoloader de Composer
Tester\Environment::setup();               # inicializa Nette Tester

$stack = [];
Assert::same(0, count($stack));   # esperamos que count() devuelva cero

$stack[] = 'foo';
Assert::same(1, count($stack));   # esperamos que count() devuelva uno
Assert::contains('foo', $stack);  # verificamos que $stack contiene el elemento 'foo'

Como ve, los llamados métodos de aserción, como Assert::same(), sirven para confirmar que el valor real coincide con el esperado.

Ya tenemos la prueba escrita y podemos ejecutarla desde la línea de comandos. La primera ejecución revelará posibles errores de sintaxis y, si no ha cometido ninguna errata, imprimirá:

$ php ArrayTest.php

OK

Pruebe a cambiar la aserción de la prueba por una falsa, como Assert::contains('XXX', $stack);, y observe qué pasa al ejecutarla:

$ php ArrayTest.php

Failed: ['foo'] should contain 'XXX'

in ArrayTest.php(17) Assert::contains('XXX', $stack);

FAILURE

Seguimos hablando de cómo escribir pruebas en el capítulo Escribir pruebas.

Instalación y requisitos

La versión mínima de PHP que requiere Tester es la 8.0 (más detalles en la tabla Versiones de PHP soportadas). La forma preferida de instalación es con Composer:

composer require --dev nette/tester

Pruebe a ejecutar Nette Tester desde la línea de comandos (sin argumentos solo imprimirá la ayuda):

vendor/bin/tester

Ejecutar las pruebas

A medida que la aplicación crece, crece con ella el número de pruebas. No sería práctico ejecutarlas una a una. Por eso Tester tiene un ejecutor masivo de pruebas al que llamamos desde la línea de comandos. Como parámetro indicamos el directorio en el que están las pruebas. Un punto significa el directorio actual.

vendor/bin/tester .

El ejecutor recorre el directorio indicado y todos sus subdirectorios y busca las pruebas, que son los archivos *.phpt y *Test.php. También encontrará nuestra prueba ArrayTest.php, porque encaja con la máscara.

Después empieza a probar. Cada prueba se ejecuta como un nuevo proceso PHP, así que se ejecuta completamente aislada de las demás. Las ejecuta en paralelo en varios hilos, lo que la hace extremadamente rápida. Y ejecuta primero las pruebas que fallaron en la ejecución anterior, para que averigüe de inmediato si logró arreglar el fallo.

Durante la ejecución de las pruebas, Tester va imprimiendo los resultados en el terminal como caracteres:

  • . – prueba superada
  • s – prueba omitida
  • F – prueba fallida

La salida puede tener este aspecto:

 _____ ___  ___ _____ ___  ___
|_   _/ __)( __/_   _/ __)| _ )
  |_| \___ /___) |_| \___ |_|_\  v2.6.0

PHP 8.5.2 (cli) | php | 8 threads

........s................F.........

-- FAILED: greeting.phpt
   Failed: 'Hello John' should be
       ... 'Hello Peter'

   in greeting.phpt(19) Assert::same('Hello Peter', $o->say('John'));

FAILURES! (35 tests, 1 failures, 1 skipped, 1.7 seconds)

Se ejecutaron 35 pruebas, una falló y una se omitió.

Seguimos en el capítulo Ejecutar pruebas.

Modo watch

¿Está refactorizando código? ¿O incluso desarrollando según la metodología TDD (Test Driven Development)? Entonces le gustará el modo watch. En este modo, Tester vigila el código fuente y se ejecuta solo automáticamente cuando cambia.

Durante el desarrollo tiene en una esquina del monitor un terminal en el que le brilla una barra de estado verde y, cuando de pronto cambia a rojo, sabe que acaba de hacer algo que no está del todo bien. En realidad es un juego estupendo en el que programa e intenta mantener el color.

El modo watch se inicia con el parámetro --watch.

Informes de cobertura de código

Tester puede generar informes con un resumen de cuánto código fuente cubren las pruebas. El informe puede ser en formato HTML legible para las personas o en Clover XML para su posterior procesamiento automático.

Vea un informe HTML de ejemplo con la cobertura de código.

Versiones de PHP soportadas

Versión Compatible con PHP
Tester 2.6 PHP 8.0 – 8.5
Tester 2.5 PHP 8.0 – 8.5
Tester 2.4 PHP 7.2 – 8.2
Tester 2.3 PHP 7.1 – 8.0
Tester 2.1 – 2.2 PHP 7.1 – 7.3
Tester 2.0 PHP 5.6 – 7.3
Tester 1.7 PHP 5.3 – 7.3 + HHVM 3.3+
Tester 1.6 PHP 5.3 – 7.0 + HHVM
Tester 1.3 – 1.5 PHP 5.3 – 5.6 + HHVM
Tester 0.9 – 1.2 PHP 5.3 – 5.6

Vale para la última versión de parche.

Tester, hasta la versión 1.7, soportaba también HHVM 3.3.0 o superior (con tester -p hhvm). El soporte se abandonó a partir de la versión 2.0 de Tester.