Parte 4: Ejemplo práctico de Pruebas De Software
Tags: tip, desarrollo, software, testing
Published: 2021-04-16 13:31:36

En esta artículo vamos a aplicar los conceptos anteriors al  crear una aplicación pequeña en laravel.

# Requerimiento funcional de la aplicación

La aplicación va a servir a una escuela, y se requiere registrar a los estudiantes
los datos a registrar son nombres completos, ciudad y fecha de nacimiento.
Se debe validar que los estudiantes sean menores de 18 años. Y que tenga todos
los datos completos.

# Crear la aplicación

Este no es un tutorial para aprender laravel, pero voy a poner los comandos que use
para generar una [aplicación inicial](https://github.com/marceloandrader/laravel-example-software-testing).

```
$ composer create-project laravel/laravel laravel-example-software-testing
$ cd laravel-example-software-testing
$ php artisan serve
```

Editar el archivo .env para usar sqlite `DB_CONNECTION=sqlite` y `DB_DATABASE=/full-path-a-la-base/software-testing-dev.sqlite` y crear la base de datos usando `sqlite3 /full-path-a-la-base/software-testing-dev.sqlite`.

[Github commit con cambio de configuración de la base](https://github.com/marceloandrader/laravel-example-software-testing/commit/42b506bcec7141c978d88ae387f7fe25c82ae90f)

Por defecto al crear una nueva aplicación, también se crean 2 tests de ejemplo  
una prueba unitaria y otra funcional:

![laravel tests](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/02g2wouta0lkyvrppmgq.png)

También voy a crear un modelo denominado Estudiante con los campos solicitados,
para poder almacenar en una base de datos.

```
$ php artisan make:model -m Estudiante
$ php artisan migrate
```

[Github commit con modelo y migración](https://github.com/marceloandrader/laravel-example-software-testing/commit/ee937a15951e2e050eef9e55ef557d6c364c9fd3)

# Casos de prueba

## Prueba unitaria

Para poder crear un estudiante debemos primero validar si su edad es menor a 18 años.
Como habíamos visto en la parte 2 generalmente las pruebas funcionales se comienzan
desde lo más pequeño hasta lo más grande. Vamos a iniciar con una prueba unitaria
para calcular la edad del estudiante. Para esto voy a generar un test unitario con:
`php artisan make:test --unit CalcularEdadTest` dentro de este test voy a comenzar creando
un objeto de tipo Estudiante seteando una fecha de nacimiento y llamando a la funcion `getEdad()` por supuesto este test va a fallar al llamar a `php artisan test tests/Unit/CalcularEdadTest.php`
al realizar esto también voy formando mi API pública ya que la forma de llamar
ciertas funciones desde el test es cómo se llamaran las funciones desde la aplicación.

Regreso a mi modelo y creo la función `getEdad` que reste la fecha actual con la fecha de nacimiento
y obtengo la edad del estudiante.

[Github commit con prueba unitaria e implementación](https://github.com/marceloandrader/laravel-example-software-testing/commit/cf80fc35fd8d26141453734e401c338463219985)

Como pueden observar en el test, se trata de verificar la mayor cantidad de posibilidades
en nuestro caso probe con 2 fechas y sin fecha para verificar que la prueba pase en los 3 casos.

![pruebas unitarias](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/52udizog3llhc7ms631r.png)

## Prueba de Integración

Un ejemplo de prueba de integración es usar más de 1 componente, en este caso podemos
probar el uso de la clase Estudiante ya en el contexto de creación desde un controlador. Para
lo cual crearemos uno usando `php artisan make:controller --model=Estudiante EstudianteController`
y comenzaré a probar la función create. Pero antes de comenzar en el controlador
crearé una prueba de integración con `php artisan make:test CrearEstudianteTest`.
Al realizar un post con datos a /estudiantes que es donde montamos el recurso en app/routes/web.php
el error fallará con error status code 200 es diferente a 201 esperado.

Implemento la función `store` en el controlador tomando los datos del request y creando un estudiante.

[Github commit con prueba de integración e implementación](https://github.com/marceloandrader/laravel-example-software-testing/commit/88850fd140f1cfd6f9f631868642c76c9f22c3ea)

Pero aun nos falta realizar la prueba con un estudiante que quiera registrarse que no
sea menor de edad. Actualizamos el test para enviar una persona adulta y al ejecutar
va a funcionar sin problema, debemos cambiar el test para esperar un resultado [422](https://httpstatuses.com/422) entidad no procesable.

[Github commit con validación de edad en controlador](https://github.com/marceloandrader/laravel-example-software-testing/commit/791606c9bb2fd9536087c1bbffbca379b03052bf)

![pruebas integración](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rfybfgpswfl2raj55lco.png)

## Pruebas de Sistema

Para realizar una prueba de sistema se debe realizar la prueba como si fuera un usuario
real manejando un browser, para esto existen varias herramientas, en nuestro caso
no he creado pantallas de usuario para poder interactuar con la aplicación por lo que no
puedo todavía crear este tipo de pruebas. Pero una vez hecho ese paso en laravel se puede instalar [dusk](https://laravel.com/docs/8.x/dusk) para realizar las pruebas usando chromedriver.

El API de dusk es muy fluida, puedes crear sesiones de usuario llenar formularios etc.

## Pruebas de Aceptación

Estas las debe realizar alguien adicional al desarrollador, en nuestro caso que es un ejemplo
pequeño y se requiere conocimientos técnicos, la prueba la puede realizar otro desarrollador
usando alguna herramienta como [curl](https://marceloandrader.github.io/blog/2021/02/03/curl-la-navaja-suiza-de-los-protocolos-de-internet/) o [imsomnia](https://insomnia.rest/) para realizar la llamada a crear un estudiante.


# Pruebas no funcionales

Se puede realizar varias pruebas no funcionales a nuestra aplicación de ejemplo.

Para el caso de pruebas de desempeño se puede probar el servicio de creación de estudiantes usando
[wrk](https://github.com/wg/wrk) para verificar la cantidad de peticiones que puede recibir.

No podemos realizar pruebas de seguridad ya que este servicio no está protegido todavía,
pero una vez que se agregue un token JWT o algún otro, se puede usar una herramienta de
pentesting para verificar. Adicional como parte de medida de seguridad del código se puede usar
`composer outdated` para escanear dependencias desactualizadas que generalmente son la causa
de problemas de seguridad.


Por motivos de tiempo hay otros tipos de pruebas que no estamos tomando en cuenta,
pero si comienzan con las pruebas anteriormente mencionadas ya están bastante bien, y su código
puede seguir creciendo en complejidad y pueden estar tranquilos al realizar cambios ya
que tienen una buena batería de tests que puede identificar errores fácil y rápidamente.