<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alfred Tejeda</title>
    <description>The latest articles on DEV Community by Alfred Tejeda (@atejedaautomation).</description>
    <link>https://dev.to/atejedaautomation</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F485746%2F1a4695b6-beed-41fd-aa30-0dab8e1cb054.png</url>
      <title>DEV Community: Alfred Tejeda</title>
      <link>https://dev.to/atejedaautomation</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/atejedaautomation"/>
    <language>en</language>
    <item>
      <title>API Testing basado en OWASP</title>
      <dc:creator>Alfred Tejeda</dc:creator>
      <pubDate>Mon, 17 May 2021 18:46:58 +0000</pubDate>
      <link>https://dev.to/atejedaautomation/api-testing-basado-en-owasp-3165</link>
      <guid>https://dev.to/atejedaautomation/api-testing-basado-en-owasp-3165</guid>
      <description>&lt;p&gt;En &lt;a href="https://dev.to/atejedaautomation/api-testing-y-no-morir-en-el-intento-1n35"&gt;API Testing y no morir en el intento&lt;/a&gt; realicé una introducción sobre qué deberíamos de probar en una API, en esta oportunidad vamos a tomar en consideración el &lt;a href="https://github.com/OWASP/API-Security/raw/master/2019/en/dist/owasp-api-security-top-10.pdf"&gt;top 10 de OWASP&lt;/a&gt; para que agreguemos casos de pruebas de introducción a seguridad.&lt;br&gt;
Para que la lectura no sea tan larga, he decidido abarcar 2 puntos por post. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OWASP (Open Web Application Security Project), es un proyecto sin ánimo de lucro a nivel mundial que busca mejorar la seguridad del software en general. Para esto, la organización se ha provisto de una serie de herramientos y documentos que explican cuáles son las brechas de seguridad más comunes en cualquier sistema de información. Sobra decir, que todos los materiales de OWASP están disponibles de manera libre (gratuita) para su libre consulta y uso.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Autorización segura a nivel de objeto:
&lt;/h2&gt;

&lt;p&gt;Las API suelen procesar sus funcionalidades a través del uso de identificadores de objetos. &lt;br&gt;
Supongamos que tenemos un endpoint al que se le indica el número de documento que queremos acceder:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;method&lt;/th&gt;
&lt;th&gt;endpoint&lt;/th&gt;
&lt;th&gt;result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/document/2000&lt;/td&gt;
&lt;td&gt;200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/document/2001&lt;/td&gt;
&lt;td&gt;200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/document/1999&lt;/td&gt;
&lt;td&gt;404 Not Found&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Podemos evidenciar que el número de documento es un valor consecutivo, por lo que un atacante puede intentar acceder a estos documentos o saber cuales se encuentra disponibles o no. Para este punto que estamos tratando como QAs (debemos ser preventivos, según definición) podemos recomendar al equipo de desarrollo que el número de documento se encuentre cifrado y podemos crear un caso de prueba que evalue que al colocar un valor no cifrado este retorne error , por lo que al ejecutar nuestras pruebas podríamos tener el siguiente resultado:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;method&lt;/th&gt;
&lt;th&gt;endpoint&lt;/th&gt;
&lt;th&gt;result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/document/2000&lt;/td&gt;
&lt;td&gt;400 Bad Request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/document/08f90c1a417155361a5c4b8d297e0d78&lt;/td&gt;
&lt;td&gt;200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;/document/1999&lt;/td&gt;
&lt;td&gt;400 Bad Request&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  2. Autenticación insegura
&lt;/h2&gt;

&lt;p&gt;Los mecanismos de autenticación a menudo se implementan de manera incorrecta, permitiendo a los atacantes comprometer los tokens de autenticación o explotar las fallas de implementación para asumir las identidades de otros usuarios temporal o permanentemente. Comprometer la capacidad del sistema para identificar al cliente / usuario, compromete la seguridad de la API en general. Pero, ¿Esto a qué hace referencia?. Veamos:&lt;br&gt;
Un usuario (puede ser atacante o no) intenta realizar un inicio de sesión exitoso:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;method&lt;/th&gt;
&lt;th&gt;endpoint&lt;/th&gt;
&lt;th&gt;result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/login user / password1&lt;/td&gt;
&lt;td&gt;Contraseña incorrecta 403 Forbidden&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/login user / password2&lt;/td&gt;
&lt;td&gt;Contraseña incorrecta 403 Forbidden&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/login user / passwordN&lt;/td&gt;
&lt;td&gt;Contraseña incorrecta 403 Forbidden&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/login user / password1000&lt;/td&gt;
&lt;td&gt;Autenticado 200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Podemos evidenciar que luego de mil intentos pudo acceder, pero se debería permitir tantos intentos, la recomendación que debemos dar es establecer un límite de intentos ya sea para suspender y/o bloquear la cuenta. En mi experiencia he visto que para evitar esta autenticación insegura se establece un límite de 3 intentos para suspensión y luego 6 para bloqueo, por otra parte he visto un límite de 3 intentos por día para suspensión, 6 intentos (entre 2 días) bloqueo preventivo y 9 intentos (entre 3 días) bloqueo definitivo. Esto por su puesto va anclado al tipo de negocio, pero la finalidad es la misma: ¡Establecer límites de intentos! Así nuestros casos de prueba se basarían en probar estos límites:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;method&lt;/th&gt;
&lt;th&gt;endpoint&lt;/th&gt;
&lt;th&gt;result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/login user / password1&lt;/td&gt;
&lt;td&gt;Contraseña incorrecta 403 Forbidden&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/login user / password2&lt;/td&gt;
&lt;td&gt;Contraseña incorrecta, queda 1 intento 403 Forbidden&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/login user / passwordN&lt;/td&gt;
&lt;td&gt;Contraseña incorrecta 403 Forbidden&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Otro escenario dónde los procesos de autenticación son inseguros puede ser el siguiente, el usuario (atacante o no) desea conocer si un correo se encuentra registrado o no, para ello utiliza la opción de recuperar contraseña. Veamos:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;method&lt;/th&gt;
&lt;th&gt;endpoint&lt;/th&gt;
&lt;th&gt;result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/password_recovey &lt;a href="mailto:usuario1@yopmail.com"&gt;usuario1@yopmail.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;El usuario no existe 200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/password_recovey &lt;a href="mailto:usuario2@yopmail.com"&gt;usuario2@yopmail.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;El usuario no existe 200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/password_recovey &lt;a href="mailto:usuarioN@yopmail.com"&gt;usuarioN@yopmail.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;El usuario no existe 200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/password_recovey &lt;a href="mailto:usuario100@yopmail.com"&gt;usuario100@yopmail.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Se enviaron las instrucciones al correo 200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Acá podemos evidenciar que el sistema está indicando si el correo existe o no, por lo que le estamos dando la respuesta que el atacante esperaba. Cómo sugerencia podemos indicar que la respuesta del servicio pueda ser "Se enviaron las instrucciones al correo" aún si el correo existe o no, de esta forma si un atacante realiza 1000 peticiones en las que todas respondan OK, entonces tendrá que tomar más tiempo para comprobar si en efecto el correo existe o no: &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;method&lt;/th&gt;
&lt;th&gt;endpoint&lt;/th&gt;
&lt;th&gt;result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/password_recovery &lt;a href="mailto:usuario1@yopmail.com"&gt;usuario1@yopmail.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Se enviaron las instrucciones al correo 200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/password_recovery &lt;a href="mailto:usuario2@yopmail.com"&gt;usuario2@yopmail.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Se enviaron las instrucciones al correo 200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/password_recovery &lt;a href="mailto:usuarioN@yopmail.com"&gt;usuarioN@yopmail.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Se enviaron las instrucciones al correo 200 OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;/password_recovery &lt;a href="mailto:usuario1000@yopmail.com"&gt;usuario1000@yopmail.com&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Se enviaron&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;las instrucciones al correo 200 OK&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Se puede sugerir alguna estrategia, una no muy común pero si efectiva que he visto en mi trayecto es enviar un mensaje indicando que ha ocurrido un error en específico pero el mensaje si es enviado en caso de coincidir coincidencia. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hasta este punto hemos visto 2 de los 10 puntos que OWASP nos menciona, tomando en consideración estos 2 puntos ya podemos ir creando casos de prueba que cumplan con requirimientos básicos de seguridad. En la próxima entrada hablaremos de la "Exposición excesiva de datos" y la "Falta de recursos y límites de uso".&lt;/p&gt;

&lt;p&gt;Puedes dejarme en los comentarios, que estrategias aplican en tu corporación y que casos de prueba crees que puedan llegar a ser o sean imprescindible para evitar estos puntos&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Me gusta escribir sobre testing en general, gracias a esto me doy cuenta de lo que me falta por aprender, también me encanta el café, por si deseas &lt;a href="https://www.buymeacoffee.com/To3Dd6m"&gt;regalarme uno :)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>owasp</category>
      <category>security</category>
    </item>
    <item>
      <title>Primer test</title>
      <dc:creator>Alfred Tejeda</dc:creator>
      <pubDate>Sun, 09 May 2021 18:06:05 +0000</pubDate>
      <link>https://dev.to/atejedaautomation/api-automation-testing-con-javascript-4kk0</link>
      <guid>https://dev.to/atejedaautomation/api-automation-testing-con-javascript-4kk0</guid>
      <description>&lt;p&gt;En el capítulo 1 realizamos la instalación de las librerías que vamos a usar en el proyecto y realizamos la configuración básica para poder usar Jasmine, en este capítulo vamos a organizar nuestro proyecto y realizar nuestro primer test. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ya que deseo utilizar en el tutorial una API real, debemos de crear una cuenta en &lt;a href="https://www.themoviedb.org/signup"&gt;TheMovieDB&lt;/a&gt;, una vez creada la cuenta, iniciamos sesión, vamos a &lt;code&gt;Ajustes / Api&lt;/code&gt; y guardamos el valor que se encuentra en &lt;code&gt;Llave API / API Key (v3 auth)&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;¡Empezemos!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuración variables de entorno
&lt;/h2&gt;

&lt;p&gt;Lo primero que vamos a realizar es preparar nuestro proyecto para usar variables de entorno por lo tanto en la raíz del proyecto vamos a crear un nuevo archivo &lt;code&gt;.js&lt;/code&gt; (yo le pondré &lt;code&gt;environment.js&lt;/code&gt; pero le pueden colocar el nombre que ustedes deseen) y dentro de él colocaremos el siguiente código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** environment.js */&lt;/span&gt;
&lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4p1k3y&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;USER_TMDB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;USER_TMDB&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;defaultUser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;PASSWORD_TMBD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PASSWORD_TMBD&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;defaultPassword&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo que estamos haciendo con estas líneas de código es exportar un &lt;a href="https://www.tutorialsteacher.com/javascript/javascript-object#:~:text=JavaScript%20object%20is%20a%20standalone,literal%20or%20object%20constructor%20syntax."&gt;objeto&lt;/a&gt; cuyos valores de las llaves están tomando los valores de las variables del sistema y en caso de no existir tomar un valor por defecto:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Nombre&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;API_KEY&lt;/td&gt;
&lt;td&gt;Nombre de la propiedad&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;process.env.API_KEY&lt;/td&gt;
&lt;td&gt;Nombre de la variable del sistema&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"4p1k3y"&lt;/td&gt;
&lt;td&gt;Valor por defecto en caso de no existir coincidencia&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;En la misma raíz del proyecto un archivo que debe de llamarse &lt;code&gt;.env&lt;/code&gt; (el archivo debe de llamarse así ya que es el valor por defecto para que &lt;code&gt;dotenv&lt;/code&gt; lea el archivo, en caso de colocar otro nombre debemos de indicarle a &lt;code&gt;dotenv&lt;/code&gt; la ruta del archivo que deseamos leer) y copiaremos lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;TuAPIKey
&lt;span class="nv"&gt;BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://api.themoviedb.org/3/
&lt;span class="nv"&gt;USER_TMDB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;UsuarioCreado
&lt;span class="nv"&gt;PASSWORD_TMBD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ContraseñaCreada
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creación de rutas
&lt;/h2&gt;

&lt;p&gt;Dentro de &lt;code&gt;./spec/support&lt;/code&gt; vamos a crear una archivo llamado &lt;code&gt;routes.js&lt;/code&gt; (En el vamos a especificar las diferentes rutas o endpoints que vamos a estar utilizando) y dentro de el vamos copiar el siguiente código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;createRequestToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/authentication/token/new&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/authentication/session/new&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Al igual que en &lt;code&gt;environment.js&lt;/code&gt; acá estamos exportando también un objeto, este contiene las diferentes rutas que vamos a estar utilizando en nuestras pruebas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Creación de nuestro primer test
&lt;/h2&gt;

&lt;p&gt;Según la documentación del &lt;a href="https://developers.themoviedb.org/3"&gt;API de TheMovieDB&lt;/a&gt; antes de poder iniciar sesión debemos de solicitar un token, este será nuestro primer caso de pruebas: Vamos a validar que en efecto este parámetro esté en la respuesta y validaremos también el código de respuesta.&lt;/p&gt;

&lt;p&gt;Dentro del directorio &lt;code&gt;./spec/&lt;/code&gt;vamos a crear un nuevo directorio llamado tests y dentro el crearemos un nuevo archivo llamado &lt;code&gt;authentication.spec&lt;/code&gt; y copiaremos el siguiente código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ENV&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ROUTES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../support/routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Testcases for /authentication route&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Request to &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ROUTES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createRequestToken&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 
    generates new token and responds 200`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;get&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;ROUTES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authentication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createRequestToken&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expires_at&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;request_token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;En las primera 4 líneas estamos importando todo lo que necesitamos tanto de librerías como los objetos que creamos para ejecutar nuestros casos de prueba. &lt;/li&gt;
&lt;li&gt;El bloque &lt;code&gt;describe&lt;/code&gt; nos permite indicar una descripción de lo que vamos a probar, dentro de el podemos crear otros describe si requieren que sean necesarios y luego declarar los casos de prueba.&lt;/li&gt;
&lt;li&gt;El bloque &lt;code&gt;it&lt;/code&gt; se usa para definir el caso de prueba&lt;/li&gt;
&lt;li&gt;Al invocar axios debemos de pasarle el método que vamos a utilizar y la url a la que hará la petición, con esto ya es suficiente para realizar una petición, pero debemos de estar pendiente de la especificación del API para saber qué mas debemos de pasarle. Para este caso la documentación no nos pide que usemos HEADERS pero si requiere queryparams, es por eso que le pasamos a axios el parámetro &lt;code&gt;params&lt;/code&gt; el cual recibe un json. &lt;a href="https://github.com/axios/axios"&gt;Documentación Axios&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Finalmente tenemos las validaciones con expect (pueden usar should) validamos que la respuesta contenga el &lt;code&gt;status&lt;/code&gt; y que este sea igual a 200, y que dentro de &lt;code&gt;data&lt;/code&gt; tengamos el request_token que usaremos más adelante para poder crear una sesión.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ejecutemos la prueba
&lt;/h2&gt;

&lt;p&gt;Para ejecutar nuestra prueba, desde una terminal ejecutamos &lt;code&gt;yarn test&lt;/code&gt; o &lt;code&gt;npm test&lt;/code&gt; y si no hemos cometido algún error de salida tendremos lo siguiente:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7VzDG3Qh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r5gjkxhgzlm1b0rqd2kn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7VzDG3Qh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r5gjkxhgzlm1b0rqd2kn.png" alt="Test output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para verificar que nuestro test funciona correctamente vamos a modificar la aserción a que espere que tenga como código de estatus un 201, esto nos debería fallar, &lt;code&gt;yarn test&lt;/code&gt; o &lt;code&gt;npm test&lt;/code&gt; nuevamente:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zPO9b82H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qayitmkifpa6girzna2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zPO9b82H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qayitmkifpa6girzna2i.png" alt="Fail test ouput"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos evidencia que en efecto nuestra prueba si está haciendo las validaciones correctamente.&lt;br&gt;
Hasta acá llega el segundo capítulo, en la próxima entrada vamos a validar un caso negativo, es decir esperar a que nos retorne error (codigo 4xx y body con mensaje de error). Los casos negativos son con los que podemos verificar si un endpoint está bien definido, si tienen los errores controlados y si en efecto el error es el que se encuentra definido. &lt;/p&gt;

&lt;p&gt;Cualquier cuda o comentario me la pueden hacer saber, responderé a la brevedad :D &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Me gusta escribir sobre testing en general, gracias a esto me doy cuenta de lo que me falta por aprender, también me encanta el café, &lt;a href="https://www.buymeacoffee.com/To3Dd6m"&gt;por si deseas regalarme uno :)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>automation</category>
      <category>testing</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>API Testing y no morir en el intento</title>
      <dc:creator>Alfred Tejeda</dc:creator>
      <pubDate>Sun, 09 May 2021 00:04:36 +0000</pubDate>
      <link>https://dev.to/atejedaautomation/api-testing-y-no-morir-en-el-intento-1n35</link>
      <guid>https://dev.to/atejedaautomation/api-testing-y-no-morir-en-el-intento-1n35</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cuando nos dicen que debemos de probar una API probablemente lo primero que se nos viene a la mente es: "utilizaré Postman" o en algunos casos SoapUI. Y no está mal; &lt;strong&gt;¿pero realmente sabemos qué debemos probar en una Rest API?.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hay varios puntos importantes a la hora de crear nuestros casos de pruebas, pero antes de hablar sobre qué debemos probar el punto más importante es entender cuál es el propósito, sabiendo esto podemos determinar nuestros datos de prueba y saber con qué debemos contrastar el resultado: con una base de datos tal vez. &lt;/p&gt;

&lt;h1&gt;
  
  
  Ahora veamos que debemos probar:
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Código de respuesta: esto determina el comportamiento que tendrá la aplicación que consume el servicio (frontend) si debe o no mostrar información; redirigir o cualquier otra acción determinada. Hay que tener presente las 5 clases o categorías:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rango&lt;/th&gt;
&lt;th&gt;Uso&lt;/th&gt;
&lt;th&gt;Descripción&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1xx&lt;/td&gt;
&lt;td&gt;Información&lt;/td&gt;
&lt;td&gt;Se recibe la solicitud y se sigue procesando&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2xx&lt;/td&gt;
&lt;td&gt;Exitoso&lt;/td&gt;
&lt;td&gt;La solicitud es recibida, comprendida y aceptada con éxito&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3xx&lt;/td&gt;
&lt;td&gt;Redireccionamiento&lt;/td&gt;
&lt;td&gt;Se deben tomar más medidas para completar la solicitud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4xx&lt;/td&gt;
&lt;td&gt;Error de cliente&lt;/td&gt;
&lt;td&gt;La solicitud contiene una sintaxis incorrecta o no se puede cumplir&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5xx&lt;/td&gt;
&lt;td&gt;Error de servidor&lt;/td&gt;
&lt;td&gt;El servidor no cumple con una solicitud aparentemente válida&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Debemos de asegurarnos que según los datos de entrada que estamos utilizando, estemos recibiendo el código de respuesta que corresponda según la definición del endpoint. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Los códigos más comunes son:&lt;/strong&gt; 200, 201, 304, 401, 402, 403, 404, 412, 500, 503.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cuerpo de respuesta:&lt;/strong&gt; si tendríamos que definir un orden de importancia el código de respuesta y cuerpo de respuestas estarían en el mismo puesto, esto determina que información va ser mostrada o utilizada desde el frontend. Esta información generalmente viene dada en formato &lt;a href="https://www.nextu.com/blog/que-es-json/"&gt;Json&lt;/a&gt; por lo que deberíamos validar el &lt;a href="https://json-schema.org/understanding-json-schema/"&gt;JsonSchema&lt;/a&gt; (sobre todo si queremos aplicar contrac testing) y la información que esta trae. A su vez debemos conocer cuales campos o pares (llave - valor) son obligatorios u opcionales y sobre estos obligatorios nuestra prueba sería intentar enviar la petición sin estos valores o enviandoles vacío o null.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Métodos admitidos por el endpoint&lt;/strong&gt;: los métodos más utilizados son GET, POST, PUT y DELETE (&lt;a href="https://developer.mozilla.org/es/docs/Web/HTTP/Methods"&gt;Lista completa de métodos&lt;/a&gt;), cuando recibimos la información del endpoint que vamos a probar siempre nos indican que método este utiliza, lo que debemos hacer es intentar hacer la misma petición pero con otro método.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cabeceras de petición&lt;/strong&gt;: las cabeceras de petición o headers permiten enviar información adicional entre el cliente y el servidor. Al igual que el cuerpo de respuesta, debemos validar que cabeceras son obligatorias y realizar la petición sin ellas, con valores errados, vacíos y nulos.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hasta acá tenemos una base para poder empezar a validar el API, en la segunda entrada de API... sin morir en el intento! Vamos a tomar en cosideración para crear nuestros casos de prueba el top 10 de OWASP y así tener algunas pruebas básicas de seguridad.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Me gusta escribir sobre testing en general, gracias a esto me doy cuenta de lo que me falta por aprender, también me encanta el café, &lt;a href="https://www.buymeacoffee.com/To3Dd6m"&gt;por si deseas regalarme uno :)&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>tutorial</category>
      <category>rest</category>
    </item>
    <item>
      <title>Instalación y configuración</title>
      <dc:creator>Alfred Tejeda</dc:creator>
      <pubDate>Mon, 03 May 2021 22:12:29 +0000</pubDate>
      <link>https://dev.to/atejedaautomation/api-automation-testing-con-javascript-o9g</link>
      <guid>https://dev.to/atejedaautomation/api-automation-testing-con-javascript-o9g</guid>
      <description>&lt;h1&gt;
  
  
  Primera parte: Instalación de librerías y configuración inicial
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Prerequisitos:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;NodeJS 10 o Superior.&lt;/li&gt;
&lt;li&gt;Editor de código (Utilizo Visual Studio Code)&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Opcional: Yarn&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cuando hablamos de API automation, muchas veces lo primero que se nos viene a la mente es usar RestAssured incluso es lo que recomiendan en grupos o comunidades, y si deseamos usar JavaScript lo primero que nos mencionan es el uso de Postman, aunque utilizamos la interfaz. En esta serie vamos a aprender a crear nuestro propio marco de trabajo para API testing utilizando diversas librerías de JavaScript. &lt;strong&gt;Empezemos!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vas a crear un nuevo directorio (yo lo llamaré tutorial-api-automation) y dentro de el iniciar un nuevo proyecto de node, para ello abrimos una terminal (recomiendo el uso de Git Bash) y una vez dentro del directorio ejecutamos npm init -y (utilizamos -y para crear valores por defecto, en caso de querer personalizar solo usemos npm init)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;tutorial-api-automation &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;tutorial-api-automation
&lt;span class="nv"&gt;$ &lt;/span&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto nos creará un nuevo archivo llamado &lt;em&gt;package.json&lt;/em&gt; , ahora procedamos instalar las librerías que vamos a utilizar; En la terminal ejecutemos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;yarn add axios chai dotenv jasmine jasmine-spec-reporter &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o en caso de no estar familiarizado con yarn podemos usar npm&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;axios chai dotenv jasmine jasmine-spec-reporter &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Librería&lt;/th&gt;
&lt;th&gt;Uso&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Axios&lt;/td&gt;
&lt;td&gt;Librería para realizar peticiones HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chai&lt;/td&gt;
&lt;td&gt;Librería para realizar las aserciones o validaciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dotenv&lt;/td&gt;
&lt;td&gt;Librería para manejo de variables de entorno&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jasmine&lt;/td&gt;
&lt;td&gt;Librería para ejecución de pruebas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jasmine Spec Reporter&lt;/td&gt;
&lt;td&gt;Librería para obtener en consola resultado de las pruebas&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Una vez finalizada la instalación de nuestras librerías podemos observar que se han creado: directorio &lt;em&gt;node_modules&lt;/em&gt;, archivo &lt;em&gt;yarn.lock&lt;/em&gt; o &lt;em&gt;package-lock.json&lt;/em&gt; y en nuestro &lt;em&gt;package.json&lt;/em&gt; debemos de tener un apartado con la sección de "devDependencies".&lt;br&gt;
Siguiente paso para la configuración vamos a ejecutar el siguiente comando en nuestra terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npx jasmine init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tp2tlv2b8516704njxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2tp2tlv2b8516704njxy.png" alt="Installation"&gt;&lt;/a&gt;&lt;br&gt;
Y esto nos crea un nuevo directorio llamado &lt;em&gt;spec&lt;/em&gt; y dentro de este un nuevo directorio llamado &lt;em&gt;support&lt;/em&gt;. Spec es el directorio por defecto para crear nuestros test, es el directorio por defecto de Jasmine.&lt;/p&gt;

&lt;p&gt;Por último paso vamos a editar el archivo package.json en la sección de scripts vamos a editar el comando test por:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"scripts: {
    "&lt;/span&gt;&lt;span class="err"&gt;test&lt;/span&gt;&lt;span class="s2"&gt;": "&lt;/span&gt;&lt;span class="err"&gt;jasmine&lt;/span&gt;&lt;span class="s2"&gt;"
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hasta acá llega esta primera parte, hemos instalado las librerías que vamos a utilizar configurado jasmine y actualizado nuestro script para la ejecución de las pruebas.&lt;br&gt;
En el próximo post vamos a crear varios directorios para organizar nuestro marco de trabajo y crear nuestro primer test.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>automation</category>
      <category>testing</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
