Como potenciar tu implementación de postman

26 abril
Ernesto Moyano, Senior QA Automation Engineer, DataArt
Como potenciar tu implementación de postman

Introducción

Si tuviste la oportunidad de trabajar en un proyecto mediano o grande que involucra llamadas a servicios REST API te habrás dado cuenta la cantidad de combinaciones que pueden surgir al invocar llamados específicos a ciertas operaciones. Tomemos el ejemplo de una pequeña red social, donde existe una administración de usuarios, creación de publicaciones y comentarios sobre esas publicaciones. Parece sencillo desde el punto de vista de un cliente que necesita desplegar su solución rápidamente al mercado. Pero si tomamos en cuenta cada una de las micro operaciones, validaciones (ya sean de pedidos o respuesta de datos), lógica de negocios, inclusive pruebas sobre diferentes ambientes, se hace evidente que necesitamos un marco de trabajo sobre alguna plataforma robusta que nos permita tener la flexibilidad de ejecutar todas nuestras pruebas dinámicamente. De este modo surgen soluciones open source como ser frameworks montados sobre Javascript y potenciado por librerías como axios, express, chai y mocha.

Pero si aún no tienes un nivel significativo de desarrollo que te permita implementar estas herramientas o simplemente el proyecto no lo permite por cuestiones de tiempo por ejemplo, quizás tu solución implique el uso de herramientas de mas alto nivel como Postman. Esta herramienta nos permite rápidamente invocar comandos REST y configurarlos mediante una interfaz amigable sin tener que interactuar con mucho código. El problema recae en que mientras mas grande es la aplicación más casos de uso debemos implementar e incrementar su complejidad.

Postman nos permite escribir casos de prueba para cada uno de nuestros pedidos, por ejemplo el análisis del código de estado de cada respuesta.

Code example

"A veces el trabajo de QA se convierte en un Arte"

Una prueba sencilla pero necesaria para validar que todas nuestras peticiones que se completaron correctamente devuelven un valor esperado para posteriormente ser procesado, por ejemplo, por una interfaz web. Tomemos otro ejemplo,  la creación de un registro que posee 2 campos (Titulo y Autor):

Code example

Nuevamente un ejemplo sencillo de 4 lineas, pero, si nuestra petición evolucionara hacia un modelo donde necesitemos una estructura de datos de 7500 lineas, el escenario cambia totalmente. Esto lleva a muchas implementaciones con postman a duplicar las peticiones, los tests y parámetros de llamada como "queryString" o "Headers". A medida que crece la aplicación crece el problema de la implementación de las pruebas, los datos de uso y el mantenimiento. Es aquí donde entra en acción nuestra habilidad para transformar esta situación en una solución escalable y de fácil mantenimiento.

Es por esto durante mi paso por proyectos gigantes de una complejidad bastante desafiante tuve que desarrollar un modelo que me permita la escalabilidad y fácil reproducción de MILES de combinaciones de casos de pruebas  el resultado es una plantilla de postman en forma de colección el cual sera caso de estudio del siguiente articulo.

Implementación

Para este ejemplo vamos a usar una api publica que simula nuestro ejemplo inicial de una red social. Puedes encontrar el link del servicio en este LINK. Para importar la colección haz click en File → Import → Folder y selecciona la carpeta del proyecto. Esto importara la plantilla de colecciones y los ambientes de prueba.

La colección se divide en tres areas:

  1. Funciones globales: Encargada de contener todas las funciones globales que se comparten en todas las colecciones.
  2. Peticiones estáticas: Cada una de las operaciones que nuestra Rest API admite.
  3. Regresiones: Casos específicos que comparten código con las peticiones estáticas.

Code example

Reuso de Código

Todas las funciones que se usarán a lo largo de los request, casos de uso y utilidades dentro de nuestra implementación están en la carpeta JS Common. Es necesario ejecutar todos los request de esta carpeta mediante el runner de la colección

Code example

Estas funciones se propagan a nivel global ya que se almacenan en variables globales que son accesibles desde cualquier punto de la aplicación. Analicemos el siguiente código:

Ejemplo de funcion global

pm.globals.set(
    "<GLOBAL_VARIABLE_NAME>",
    function loadUtil() {
        let util = {};
 
        util.example = (params) => {
            // TODO
                       console.log("It Works!")
        }
 
        return util;
    } + "; loadutil();"
);

Code example

En este ejemplo estamos almacenando una función en una variable global para ser consumida posteriormente e interpretada por el método eval() de Javascript. Una implementación de este código almacenandola bajo el nombre GLOBAL_VARIABLE_NAME = utility, seria algo similar a :

const utils = eval(pm.globals.get("utility"));
 
utils.example()

De este modo estaríamos usando variables definidas en un ámbito global sin la necesidad de almacenar cada función bajo un alias como se hacia históricamente en postman. 

Parámetros por defecto

//TODO

Autenticación

Las aplicaciones modernas tienen un abanico muy variado de autenticaciones, pero la mas frecuente y simple de analizar es la autenticación simple por tokens, ademas de ser usada por nuestro ejemplo. Para ello es necesario agregar un header con el valor generado en este LINK y hacer uso de las funciones de autenticación contenidas en JS Common → Globals - Utils → addAuthentication(). Esta implementación dependerá de cada caso ya que cada API tiene un método de recepción de información diferente.

Herencia de Casos de Prueba

Al escribir los casos de prueba no es necesario copiar y pegar multiples entradas en cada uno de los request, una colección provee un mecanismo de herencia de ejecución de acciones antes y después de la ejecución de cada request. Este comportamiento se puede editar desde General Template → Pre-request Script | Tests. Agregando código en estas 2 secciones nos permitirá que nuestros request hereden estos comportamientos antes y después de cada ejecución.

En este ejemplo el cuerpo del pre-request script a nivel de colección tiene un selector definido por el nombre de suite de cada caso ed uso, por ejemplo:

Collection Pre-Request

const suiteName = pm.info.requestName.split("-")[0].replace(/\s/g, "").toLowerCase();
const test = eval(pm.globals.get("test"));
const utils = eval(pm.globals.get("utils"));
const visualizer = eval(pm.globals.get("visualizer"));
 
switch (suiteName) {
    case 'search':
        // Run user common tests
        test.usersCommonTests();
 
        // Parse responses
        visualizer.parseUsersResponse()
        break;
    case 'create':
        // Run user common tests
        test.usersCommonTests();
        break;
    case 'update':
        // Run user common tests
        test.usersCommonTests();
        break;
    default:
        console.warn("Suite not found")
}

Los tests que se declaran a nivel global están definidos en General Template → JS Common → Globals - Tests

Visualización

A veces nos topamos con respuestas de servicios que son gigantes y requieren su análisis e interpretación de datos, lo cual no es una tarea sencilla si tomamos como base una respuesta de un objeto JSON de 8700 lineas. Es por esto que construir un visualizador nos permitirá la rápida lectura y procesamiento de datos directamente en el framework de postman. Para esto podemos usar una función prevista:

Postman visualizer

pm.visualizer.set(template, {
    response: pm.response.json(),
});

donde la variable "template" es un tipo string que contiene la plantilla HTML que contiene los datos, en este caso un json, para ser renderizada por la pestaña "Visualize" en la UI.

Code example

Todos los visualizadores están definidos en General Template → JS Common → Globals - Visualizers.

Esquema de Datos

TODO

 

Logging

Si bien postman nos provee con un mecanismo simple de loggeo de datos mediante el conocido comando console.log, para potenciar aun mas nuestro análisis sobre la ejecución de casos de uso puedes hacer uso de una version extendida de log disponible en JS Common → Globals - Logger → Logger

Code example

Si te interesa este tema y te gustaría ser parte de nuestro equipo de trabajo, envianos tu CV a: careers.rla@dataart.com