Skip to content

Testing de APIs REST

enfoqueNativo edited this page Aug 2, 2022 · 2 revisions

Testing de APIs REST

El testeo automatizado se basa en la librería PHPUnit. Cada operación que desea testear puede tener sus particularidades y será necesario testearla de diferentes maneras. Es recomendable leer la referencia de PHPUnit para entener el funcionamiento básico. En particular, es importante comprender el funcionamiento de los Test Doubles o Mocks. PHPUnit

Por otro lado, es necesario cierto conocimiento de la librería de REST para poder mockear los aspectos que no se desean testear (no se desean controlar), y focalizarse en los aspectos del negocio que se requieren probar automatizadamente. Para operaciones más avanzadas se deberá investigar el funcionamiento de la librería y crear mocks propios para reemplazar las dependencias que se requieran.

Estructura

Instalación recomendada

Se recomienda instalar PHPUnit globalmente de la siguiente manera (linux):

#Debian/Ubuntu
sudo apt-get install phpunit

#Sino
wget https://phar.phpunit.de/phpunit.phar
chmod +x phpunit.phar
mv phpunit.phar /usr/local/bin/phpunit

Ejecutar Tests

Para correr los tests se debe ejecutar por medio de un archivo de configuración que se encargar de cargar los autoloads y la librería.

phpunit -c test/php-unit.xml 

Convenciones

  • Crear la carpeta test a la altura de php, de forma tal que sea gemela de php (es decir, imite la estructura de dicha carpeta).
  • Crear los archivos bootstrap_test.php y php-unit.xml en la carpeta /test para inicializar los tests.
  • Para testear una clase [clase], crear un archivo [clase]Test.php en la carpeta gemela, dentro de /test
  • Para cada clase de test, extender la clase PHPUnit_Framework_TestCase o hija.
  • El nombre de los métodos de test, comienzan con test, y luego una referencia al método que testea y/o al aspecto que testea, por ejemplo testGetListFiltro, testGetList, etc.

Ejemplo

Testeo de APIs REST

Para las APIs de cada proyecto, se recomienda hacer un testeo end-to-end, ya que es el aspecto visible al usuario y es difícil de testear manualmente, independientemente de los testeos unitarios de las clases intervinientes. Por ejemplo, el testeo de un recurso de la API estará en:

require_once 'rest_test_case.php';

class recurso_personasTest extends rest_test_case
}}}

Un caso típico de uso para el testeo end-to-end de las APIs REST es el siguiente, en el setUp() (se ejecuta antes de cada test) se realiza lo siguiente:

	parent::setUp();
	$app = $this->setupRest();
	$user = new \rest\seguridad\rest_usuario();
	$user->set_usuario('user');
	$this->mock_autenticador($user, $app);

Primero se crea la aplicación con la misma configuración que el sistema (en caso de realizar cambios significativos, sería importante incorporarlos en los tests, creando una clase que pise al método setupRest();).

Luego se mockea al servicio de autenticación. Si se observa el código fuente del mismo, esto implica 2 cosas, primero indicarle a la librería que en lugar de su autenticador, use el mock, y segundo, cuando al servicio le pidan un usuario, devuelva el usuario que se está indicando. Esto evita tener que hacer una autenticación real, y permite probar con un mayor control. Luego, antes de ejecutar se realiza un mock del request (para simular las variables $_GET, $_POST, que realmente no se setean ya que no se está realizando un pedido HTTP) o de la vista para que no escriba en pantalla, sino que devuelva los datos crudos en formato de arreglo.

Del mismo modo que se hacen mocks para las clases del proyecto, se pueden realizar para el modelo, dependiendo del caso. Por ejemplo, si un servicio requiriese de la lectura de un archivo, puede crearse un archivo de testeo y con un mock hacer que se lea de ese archivo, o bien que devuelva un contenido dado sin realmente leer nada.

Un ejemplo para testear un aspecto de GET /personas es el siguiente:

	$response = $this->ejecutar('GET', '/personas');
	$personas = $response->get_data();
	$this->assertEquals($response->get_status(), 200);
	$this->assertTrue(count($personas) > 0);
	$this->assertArrayHasKey('id', $personas[0]);
	$this->assertArrayHasKey('nombre', $personas[0]);
	$this->assertArrayHasKey('fecha_nac', $personas[0]);

Aquí se hace un pedido, se chequea que contenga al menos un registro y se examina que el primero tenga seteados los campos esperados. Sería deseable contar con bases de prueba controladas, en las que puedan asumirse (y testear) más cosas sobre los datos, pero el manejo de las mismas queda a discreción de cada proyecto. De cualquier modo, un test de este estilo asegura que al menos se devuelven datos, y no hay por ejemplo una excepción o un formato inválido.