Creando Unit testing en CAPm para BAS

En entradas anteriores hemos visto como crear tests automáticos para nuestras para nuestras aplicaciones SAPUI5 ya sean test unitarios o UATs.

Y… En CAPm ¿es possible? Pues la respuesta es sencilla, SI. En la entrada de hoy veremos lo fácil que es preparar test unitarios que podremos ejecutar por ejemplo en nuestro BAS de manera rápida para asegurarnos que nuestros cambios no rompen nada.

Da potencia y flexibilidad a tus tests con Jest

Para automatizar las pruebas utilizaremos JEST, un framework para testing basado en javascript. En el definiremos los escenarios de prueba y mediante un comando nos generará un informe con los test.

Preparación del entorno

Partiremos de un cap básico, para esta prueba, utilizaremos un CAPm generado con el template de BAS y añadiendo los ficheros de ejemplo del mismo template.

Para poder añadir n abanico de pruebas mas grande, quitaremos la limitación de solo lectura (@readonly) de la entidad libros:

Ahora que ya tenemos nuestro CAPm mínimo apunto vamos a añadirlo necesario para JEST.

  • Lo primero será crear una carpeta en la raiz del proyecto llamada “test”
  • En la carpeta que acabamos de crear, añadiremos un fichero terminado en test.js, en mi caso añadiré odata.test.js
  • Antes de llenar el fichero con los test vamos a preparar el entorno instalando las librerías necesarias. Para ello ejecutaremos el instalador de paquetes npm con las siguientes librerías:
npm install chai -D
npm install chai-as-promised -D
npm install chai-subset -D
npm install jest -D

Es importante tener en cuenta que añadiremos el parámetro -D para indicar que estas dependencias solo las necesitaremos en entornos de desarrollo. Esté sera el resultado en nuestro fichero package.json.

  • El siguiente paso es añadir el comando en el fichero package.json para disparar los test “test”: “jest”

Ya tenemos listo el entorno para poder hacer los test, lo siguiente será preparar algunos test.

Preparando test unitarios

Vamos a rellenar el fichero odata.test.js que hemos creado en nuestra carpeta test para validar de manera rápida si nuestro odata funciona de manera correcta.

Preparando el fichero

  • Lo primero que añadiremos será la libreria que interpretara los ficheros cds de nuestro proyecto:
const cds = require('@sap/cds/lib')
  • Lo siguiente será indicar el directorio donde encontrar los test y podremos añadiremos la configuración de despliegue de nuestro servidor de pruebas. En este caso, no añadiremos configuración del despliegue, así quedará:
const { GET, POST, PATCH, expect } = cds.test(__dirname+'/..')

Preparando el un bloque de test

Ahora abriremos un bloque de test, esto lo haremos con la función describe y le añadiremos un texto. Si pasamos todos los test del bloque descrito en “describe” en nuestro informe aparecerá el tic verde.

describe('Basic OData metadata', () => {

Preparando el test

En el primer test validaremos si el metadata tiene la información que nos indique que nuestro odata es del tipo V4 y validaremos si tenemos la entidad Book definida

  • Cada test lo iniciaremos con la función it y le añadiremos una descripción.
it('serves $metadata documents in v4', async () => {
  • Lo siguiente es preparar las instrucciones de la llamada, esto lo haremos añadiendo el método a ejecutar (GET/POST/PUT/DELETE) y declarando unas variables para el resultado:
      const { headers, status, data } = await GET `/catalog/$metadata`
      expect(status).to.equal(200)
      expect(headers).to.contain({
        'content-type': 'application/xml',
        'odata-version': '4.0'
      })

Lo que hemos añadido en el punto anterior es una verificación donde una vez realizada la llamada, validamos que nos devuelve un código de error 200 y que el metadata nos llega en formato XML y este tiene una cabezara que indica que el protocolo odata es 4.0.

  • Adicionalmente añadiremos también una validación para validar que nuestra entidad book esta presente en el metadata del servicio.
      expect(data).to.contain("<EntitySet Name=\"Books\" EntityType=\"CatalogService.Books\"/>")

Ejecutando nuestro primer test

Nuestro primer test ya esta listo. Vamos a ejecutar los test para validar el servicio, lo que haremos es ejecutar el comando: npm run test. Este será el resultado:

Test adicionales

Test GET

Vamos a añadir un par de test mas para validar nuestra API:

El primero es un GET donde validaremos si como mínimo tenemos un registro concreto, para ello añadiremos el siguiente código:

describe('Basic OData GET', () => {

    it('GET /processor/Travel', async () => {
        const { data } = await GET('/catalog/Books')
        expect(data.value).to.containSubset([{
            ID: 2,
            title: "Jane Eyre",
            stock: 500,
        }])
      })

      it('GET /processor/Travel', async () => {
        const { data } = await GET('/catalog/Books?$filter=ID eq 2',{
            params: { $select: "title" }
          })
        expect(data.value).to.containSubset([{
            title: "Jane Eyre"
        }])
      })   

}) 

Y este es el resultado:

Test POST

Vamos ahora a añadir un registro nuevo y validar si el registro se ha añadido de manera correcta:

describe('Basic OData POST', () => {
    it('POST /catalog/Books', async () => {
    const { status } = await POST(`/catalog/Books`, {
        ID: 3,
        title: "New",
        stock: 1,
    })
    expect(status).to.equal(201)
    })

    it('GET /processor/Books', async () => {
        const { data } = await GET('/catalog/Books(3)',{
            params: { $select: "title" }
          })
        expect(data.value).to.containSubset({
            title: "New"
        })
      })  

})

Y este es el resultado:

… pero… ¿qué pasaría en caso de error? Para ello vamos a cambiar el resultado esperado después del post y este es el resultado:

Fichero final de ejemplo

Aquí os dejo el fichero de ejemplo para que tengáis una base de trabajo:

describe('Basic OData Metadata', () => {

    it('serves $metadata documents in v4', async () => {
      const { headers, status, data } = await GET `/catalog/$metadata`
      expect(status).to.equal(200)
      expect(headers).to.contain({
        'content-type': 'application/xml',
        'odata-version': '4.0',
      })
      expect(data).to.contain("<EntitySet Name=\"Books\" EntityType=\"CatalogService.Books\"/>")
    })
}) 

describe('Basic OData GET', () => {

    it('GET /processor/Books', async () => {
        const { data } = await GET('/catalog/Books')
        expect(data.value).to.containSubset([{
            ID: 2,
            title: "Jane Eyre",
            stock: 500,
        }])
      })

      it('GET /processor/Books', async () => {
        const { data } = await GET('/catalog/Books?$filter=ID eq 2',{
            params: { $select: "title" }
          })
        expect(data.value).to.containSubset([{
            title: "Jane Eyre"
        }])
      })      

}) 

describe('Basic OData POST', () => {
    it('POST /catalog/Books', async () => {
    const { status } = await POST(`/catalog/Books`, {
        ID: 3,
        title: "New",
        stock: 1,
    })
    expect(status).to.equal(201)
    })

    it('GET /processor/Books', async () => {
        const { data } = await GET(`/catalog/Books(3)`,{
            params: { $select: "title" }
          })
        expect(data).to.containSubset({
            title: "New dos"
        })
      })  

})

Como veis ya no es escusa tener una minima batería de test automatizados para añadir una capa mas de pruebas en nuestros backends bajo BTP.

Con este framework también podemos automatizar las pruebas en un GIT o añadir restricciones para que los commits no estén permitidos si no se pasan los test.

Como siempre suscribete, dale a la campanita de notificaciones y comparte en redes para estar a la última. Vota Like / Dislike para aportar feedback.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.