En este tutorial, aprenderemos qué son las pruebas, los diferentes tipos de pruebas, y luego usaremos Puppeteer para realizar pruebas de extremo a extremo en nuestra aplicación. Al final de este tutorial, debería ser capaz de probar sus aplicaciones de extremo a extremo fácilmente con Puppeteer.
¿Qué es el titiritero?
Titiritero es una biblioteca de nodos que proporciona una API de alto nivel para controlar Chrome o Chromium a través del protocolo DevTools. Puppeteer se ejecuta sin cabeza de forma predeterminada, pero se puede configurar para ejecutar Chrome o Chromium completo (sin cabeza).
Requisitos previos
Para este tutorial, necesita un conocimiento básico de JavaScript, ES6 + y Node.js.
También debe haber instalado la última versión de Node.js.
Estaremos usando hilo a lo largo de este tutorial. Si no tienes yarn
ya instalado, instálelo desde esta página.
También debe conocer los conceptos básicos de Titiritero. Para comprender los conceptos básicos de Titiritero, echa un vistazo este sencillo tutorial.
Para asegurarnos de que estamos en la misma página, estas son las versiones utilizadas en este tutorial:
- Nodo 13.3.0
- NPM 6.13.2
- hilo 1.21.1
- titiritero 2.0.0
- crear-reaccionar-aplicación 3.3.0
Introducción a las pruebas
En lenguaje sencillo, las pruebas Es un proceso para evaluar que la aplicación funciona como se esperaba. Ayuda a detectar errores antes de que se implemente su aplicación.
Hay cuatro tipos diferentes de pruebas:
- Prueba estática: utiliza un sistema de tipo estático como Mecanografiado, MotivoML, Flujo o una pelusa como ESLint. Esto ayuda a capturar errores básicos como errores tipográficos y sintaxis.
- Examen de la unidad: se prueba la parte más pequeña de una aplicación, también conocida como unidad.
- Pruebas de integración: múltiples unidades relacionadas se prueban juntas para ver si la aplicación funciona perfectamente en combinación.
- Pruebas de extremo a extremo: toda la aplicación se prueba de principio a fin, como lo haría un usuario normal, para ver si se comporta como se esperaba.
El trofeo de prueba por Kent C. Dodds es una gran visualización de los diferentes tipos de pruebas:
El trofeo de prueba debe leerse de abajo hacia arriba. Si realiza estos cuatro niveles de prueba, puede estar lo suficientemente seguro con el código que envía.
Ahora realicemos pruebas de extremo a extremo con Puppeteer.
Pruebas de extremo a extremo con titiritero
Arranquemos un nuevo proyecto React con crear-reaccionar-aplicación, también conocido como CRA. Continúe y escriba lo siguiente en la terminal:
$ npx create-react-app e2e-puppeteer
Esto iniciará un nuevo proyecto React en un e2e-puppeteer
carpeta. Gracias a lo último create-react-app
versión, esto también instalará biblioteca de prueba por defecto para que podamos probar nuestras aplicaciones fácilmente.
Entra al e2e-puppeteer
directorio e inicie el servidor escribiendo lo siguiente en el terminal:
$ cd e2e-puppeteer
$ yarn start
Debe tener un aspecto como este:
Nuestra App.js
Se ve como esto:
import React from 'react';
import logo from './logo.svg';
import './App.css'; function App() { return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> );
} export default App;
Estaremos probando el App.js
función y el código se escribirá en App.test.js
. Así que adelante y ábrete App.test.js
. Debe tener el siguiente contenido:
import React from 'react';
import { render } from '@testing-library/react'; // 1
import App from './App'; test('renders learn react link', () => { // 2 const { getByText } = render(<App />); // 3 const linkElement = getByText(/learn react/i); // 4 expect(linkElement).toBeInTheDocument(); // 5
});
Esto es lo que sucede en el código anterior:
- We
import
lasrender
funcionar desde el@testing-library/react
paquete. - Luego usamos el global
test
funcionar desde Broma, que es nuestro corredor de prueba instalado de manera predeterminada a través de CRA. El primer parámetro es una cadena que describe nuestra prueba, y el segundo parámetro es una función donde escribimos el código que queremos probar. - A continuación, representamos el
App
componente y desestructurar un método llamadogetByText
, que busca todos los elementos que tienen un nodo de texto contextContent
. - Entonces, llamamos al
getByText
funcionar con el texto que queremos verificar. En este caso, verificamoslearn react
con la bandera insensible a mayúsculas y minúsculas. - Finalmente, hacemos la afirmación con el
expect
función para verificar si el texto existe en el DOM.
Esto viene por defecto cuando arrancamos con CRA. Continúe y abra otra terminal y escriba lo siguiente:
$ yarn test
Cuando muestra un mensaje, escriba a
para ejecutar todas las pruebas Ahora deberías ver esto:
Ahora probemos esta aplicación con pruebas de extremo a extremo.
Probar el repetitivo con titiritero
Continúa e instala puppeteer
como dependencia de desarrollo escribiendo lo siguiente en el terminal:
$ yarn add -D puppeteer
Ahora abre App.test.js
y pegue lo siguiente:
import puppeteer from "puppeteer"; // 1 let browser;
let page; // 2
beforeAll(async () => { browser = await puppeteer.launch({ headless: false }); page = await browser.newPage(); await page.goto("http://localhost:3000/");
}); // 3
test("renders learn react link", async () => { await page.waitForSelector(".App"); const header = await page.$eval(".App-header>p", e => e.innerHTML); expect(header).toBe(`Edit <code>src/App.js</code> and save to reload.`); const link = await page.$eval(".App-header>a", e => { return { innerHTML: e.innerHTML, href: e.href }; }); expect(link.innerHTML).toBe(`Learn React`); expect(link.href).toBe("https://reactjs.org/");
}); // 4
afterAll(() => { browser.close();
});
Esto es lo que estamos haciendo en el código anterior:
- En primer lugar, importamos el
puppeteer
empaquetar y declarar algunas variables globales,browser
ypage
. - Entonces tenemos el
beforeAll
función proporcionada por Jest. Esto se ejecuta antes de que se ejecuten todas las pruebas. Aquí, lanzamos un nuevo navegador Chromium llamandopuppeteer.launch()
, mientras configuraheadless
modo afalse
entonces vemos lo que está pasando. Luego, creamos una nueva página llamandobrowser.newPage()
y luego ve a la URL de nuestra aplicación Reacthttp://localhost:3000/
llamando alpage.goto()
función. - A continuación, esperamos el
.App
selector para cargar. Cuando se carga, obtenemos elinnerHTML
of.App-header>p
selector utilizando elpage.$eval()
método y compararlo conEdit
src/App.js
y guardar para recargar. Hacemos lo mismo con el.App-header>a
selector. VolvemosinnerHTML
yhref
y luego los comparamos conLearn React
yhttps://reactjs.org/
respectivamente para probar nuestra afirmación con Jestexpect()
función. - Finalmente, llamamos al
afterAll
función proporcionada por Jest. Esto se ejecuta después de ejecutar todas las pruebas. Aquí, cerramos el navegador.
Esta prueba debería ejecutarse automáticamente y darle el siguiente resultado:
Sigamos adelante y hagamos una aplicación de contador.
Convertir el Boilerplate a una aplicación de contador
En primer lugar, edite un poco de CSS cambiando App.css
a lo siguiente:
.header { font-size: 56px; text-align: center;
} .counter-app { display: flex; justify-content: space-around;
} button { background-color: navajowhite; font-size: 32px;
} .count { font-size: 48px;
}
Ahora cambia App.js
a lo siguiente:
import React, { useState } from "react";
import "./App.css"; function App() { const [count, setCount] = useState(0); return ( <> <h1 className="header">Counter</h1> <div className="counter-app"> <button className="increment" onClick={() => setCount(count + 1)}> Increment </button> <div className="count">{count}</div> <button className="decrement" onClick={() => setCount(count - 1)}> Decrement </button> </div> </> );
} export default App;
Aquí, estamos haciendo una aplicación de contador simple con dos botones, Increment
y Decrement
. Al presionar el Increment
botón, el contador se incrementa en 1, y presionando Decrement
botón, el contador se reduce en 1. Se ve así:
Probar la aplicación de contador con Titiritero
Ahora cambia el App.test.js
a lo siguiente:
import puppeteer from "puppeteer"; let browser;
let page; beforeAll(async () => { browser = await puppeteer.launch({ headless: false }); page = await browser.newPage(); await page.goto("http://localhost:3000/");
}); // 1
test("renders counter", async () => { await page.waitForSelector(".header"); const header = await page.$eval(".header", e => e.innerHTML); expect(header).toBe("Counter");
}); // 2
test("sets initial state to zero", async () => { await page.waitForSelector(".counter-app"); const count = await page.$eval(".count", e => e.innerHTML); expect(count).toBe("0");
}); // 3
test("increments counter by 1", async () => { await page.waitForSelector(".counter-app"); await page.click(".increment"); const count = await page.$eval(".count", e => e.innerHTML); expect(count).toBe("1");
}); // 4
test("decrements counter by 1", async () => { await page.waitForSelector(".counter-app"); await page.click(".decrement"); const count = await page.$eval(".count", e => e.innerHTML); expect(count).toBe("0");
}); afterAll(() => { browser.close();
});
Aquí guardamos el beforeAll
y afterAll
funcionan igual que antes, donde inicializamos un navegador y vamos a http://localhost:3000/
in beforeAll
y cerramos el navegador en afterAll
. Luego, hacemos lo siguiente:
- Verificamos si el texto
Counter
se rinde. Para eso, esperamos el.header
selector para cargar. Entonces usamospage.$eval()
para obtener elinnerHTML
of.header
selector. Y luego finalmente hacemos la afirmación de verificar siCounter
se rinde. - A continuación, verificamos si el estado inicial es cero. Esperamos el
.counter-app
selector para cargar. Entonces obtenemos elinnerHTML
del desplegable.count
selector. Finalmente comparamos si elcount
is0
. Tenga en cuenta que estamos usando unstring
mientras nuestro estado es unnumber
. Esto es porqueinnerHTML
siempre devuelve unstring
. - Aquí, verificamos si al hacer clic en el botón se incrementa el estado en 1. Primero, esperamos que
.counter-app
selector para cargar. Luego hacemos clic en el.increment
botón. Esto debería aumentar el estado de0
a1
. Entonces obtenemos elinnerHTML
del desplegable.count
selector. Luego lo comparamos con1
, como el nuestroincrement
la función siempre debe aumentar el estado en1
. - El botón de disminución debería disminuir el estado en 1. Funciona de la misma manera que el botón de incremento. Primero, esperamos el
.counter-app
selector para cargar. Luego hacemos clic en el.decrement
botón. Esto debería disminuir el estado de1
a0
. Observe que el estado era1
después de hacer clic en elincrement
botón. Entonces obtenemos elinnerHTML
del desplegable.count
selector. Luego lo comparamos con0
, como el nuestrodecrement
la función siempre debe disminuir el estado en1
.
El resultado ahora debería verse así:
Conclusión
En este tutorial, aprendimos sobre diferentes tipos de pruebas: pruebas estáticas, pruebas unitarias, pruebas de integración y pruebas de extremo a extremo. Luego realizamos pruebas de extremo a extremo en nuestro repetitivo, arrancadas con la ayuda de create-react-app
.
Más tarde, convertimos la aplicación en una aplicación de contador. Y finalmente realizamos pruebas de extremo a extremo en la aplicación de contador.
La biblioteca Puppeteer es útil no solo para realizar pruebas de extremo a extremo, sino también para realizar diferentes tipos de automatización del navegador. Puppeteer está respaldado por Google y se mantiene activamente, así que asegúrese de verificar documentos para comprender los casos de uso de gran alcance que ofrece.
Puede encontrar el código para este tutorial en GitHub.
Para obtener más información sobre las pruebas, SitePoint Premium proporciona una variedad de recursos, que incluyen:
Fuente: https://www.sitepoint.com/puppeteer-end-to-end-testing/?utm_source=rss