Como hacer testing en Bash
Quizás el título de este capítulo del tutorial sea algo pretencioso. Pero desde luego, si aplicas el testing en Bash, si no eres ya un máster en Bash, vas camino de conseguirlo a marchas forzadas, eso sin lugar a dudas. Si has revisado, estudiado y practicado todos los otros capítulos del tutorial, este ya te viene de corrido. Es la pieza que te faltaba para completar el puzzle.
El testing no te garantiza que tus scripts en Bash vayan a estar exentos de errores, aunque mejoran sensiblemente la calidad de tu código, y te garantizan unos mejores resultados. Desde luego que si realizas todos los casos de uso, estarás muy cerca del éxito total.
Pero ¿que es esto del testing?¿como puedes aplicar el testing en Bash?
Como hacer testing en Bash
Por simplificar al máximo y aclarar un poco de que va esto del testing, indicarte que se trata de un proceso que te permite verificar y validar una funcionalidad o un caso o casos de uso.
Pongamos que implementas una función en Bash para convertir una frase a mayúsculas. El testing te permitiría verificar que esa funcionalidad que has implementado funciona de forma correcta. Así, le aplicas una serie de casos de uso, y compruebas que el resultado es el correcto. Este mismo caso, lo veremos en un ejemplo, para que veas lo práctico y funcional que es esto.
shUnit2
De los diferentes framework que hay disponibles para hacer test unitarios con Bash, me he quedado con shUnit2
. Es el que mas sencillo me ha resultado para la configuración y puesta en marcha. Además los scripts de testeo siguen siendo scripts en Bash, con lo que se pueden revisar al igual que harías con cualquier otro script.
shUnit2
es un framework para realizar test unitarios de scripts basados en Bourne. Está diseñado para tener un comportamiento y funcionalidad similar a la que ofrece JUnit
, PyUnit
, etc.
Los shell que se han probado son,
sh
bash
dash
ksh
zsh
Instalación y configuración
El primera paso es preparar nuestro campo de pruebas, por llamarlo de alguna manera. Aunque el directorio principal puede ser cualquiera, en este caso, le he llamado testing
para que quede claro. En tu caso, realmente solo necesitas que dentro de tu proyecto tengas un directorio llamado test
que es donde se situará todo lo que necesitas para realizar el testing. El ejemplo que he realizado lo puedes encontrar en un repositorio en GitHub llamado testing en bash.
Una vez creado este directorio, y los directorios necesarios, donde tengas el código y lo que tu vayas a necesitar, el siguiente paso, es añadir un submodule
de Git
que te permitirá realizar los test.
Los pasos a realizar serían los siguientes,
mkdir testing
cd testing
mkdir src test
git init
git submodule add https://github.com/kward/shunit2.git test/shunit2
Dentro del directorio src
tienes que añadir tus scripts, mientras que en el directorio test
, colocarás tus test unitarios que quieras probar.
Configurando nuestro sistema de pruebas
Dentro del directorio test
encontrarás el archivo test1.sh
con algunos test que veremos mas adelante. En este archivo he añadido al final del mismo, las siguientes líneas de código. Es importante que este código esté al final,
# --- 👇 Aquí los scripts con el código a probar 👇 ---
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
oneTimeSetUp(){
source "${SCRIPT_DIR}/../src/sample.sh"
}
# --- 👇 la librería que nos permite realizar las pruebas 👇 ---
# Load shUnit2
source "${SCRIPT_DIR}/shunit2/shunit2"
La variable $SCRIPT_DIR
la he definido para tener el directorio en el que se encuentra el script de prueba. Está definido como ruta absoluta, lo que te ayudará para poder trabajar tanto con tus scripts como cono los test.
Funciones de ayuda
Existen una serie de funciones de ayuda que te facilitarán la realización de testing de forma mucho mas cómoda.
Asserts
Estas son las funciones que te permitirán realizar las comparaciones entre lo que debe obtenerse y lo que se obtiene. Estas son las siguientes,
assertEquals
assertNotEquals
assertSame
assertNotSame
assertContains
assertNotContains
assertNull
assertNotNull
assertTrue
assertFalse
Lo mismo tienes para los errores,
fail
failNotEquals
failSame
failNotSame
failFound
failNotFound
Saltando pruebas
En ocasiones y por las circunstancias que sean, sucede que necesitas saltar alguna de las pruebas. Por ejemplo, cuando la parte del código correspondiente no la tienes ya preparada, o porque no la necesitas en ese momento. En este caso, tienes tres funciones que te ayudarán,
startSkipping
da inicio a la parte del código que quedará excluido del testendSkipping
exactamente igual que el anterior pero marca el fin.isSkipping
permite conocer si la línea está afectada de skipping.
Librerías y otras dependencias
Es posible que necesites realizar una serie de operaciones antes de realizar un test o después de realizarlo. Por ejemplo, imagina que en tu test creas un archivo temporal. Lo suyo, es que una vez terminado el test, borres ese archivo temporal. Pues estas funciones que te voy a indicar a continuación son útiles para realizar precisamente ese trabajo. Así, tienes las siguientes,
oneTimeSetUp
esta función se ejecuta antes de que se ejecuten los test. Solo se ejecutará una vez. En esta función deberías introducir aquellas variables de entorno que quieras que estén disponibles para tus propios test.oneTimeTearDown
. Esta sería la función complementaria a la anterior, en el sentido de que se ejecuta al terminar todos los tests, y solo se ejecutará una vez. Al igual que en el caso anterior te resultará de interés para el caso de que quieras dejar tu campo de pruebas limpio como antes de comenzar las mismas.setUp
esta función se ejecutará antes de cada test.tearDown
lo mismo que la anterior para al final de cada test.
Algunos ejemplos
Aunque puedes encontrar muchos mas ejemplos en el repositorio de GitHub, te indico algunos para que veas lo sencillo que puede ser crear tus test unitarios y mejorar sensiblemente la calidad de tu código.
testApi200(){
result=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE "https://httpbin.org/status/200" -H "accept: text/plain")
assertEquals 200 "${result}"
}
testSaludo(){
result=$(curl -s -X GET "https://httpbin.org/base64/SG9sYQo%3D" -H "accept: text/html")
assertEquals "Hola" "${result}"
}
Puedes encontrar muchos mas ejemplos en el repositorio que mi repositorio de GitHub.
El vídeo
En este vídeo te explico el funcionamiento de shUnit2 y como puedes integrarlo con tus scripts para hacer baterías de test.
Imagen de portada de Joshua Lawrence
La entrada Como hacer testing en Bash aparece primero en Atareao.