
Si bien es importante tener una API bien probada, una cobertura de prueba sólida es imprescindible para cualquier aplicación de React. Las pruebas aumentan la confianza en el código y ayudan a prevenir errores de envío a los usuarios.
Es por eso que nos centraremos en las pruebas en esta publicación, específicamente para las aplicaciones React. Al final, estará listo y funcionando con pruebas usando Jest y Enzyme.
¡No se preocupe si esos nombres no significan nada para usted porque es hacia donde nos dirigimos ahora mismo!
Instalación de las dependencias de prueba
Jest es un marco de prueba unitario que hace que probar aplicaciones React sea bastante fácil porque funciona a la perfección con React (porque, bueno, el equipo de Facebook lo hizo, aunque es compatible con otros marcos de JavaScript). Sirve como un corredor de pruebas que incluye una biblioteca completa de pruebas predefinidas con la capacidad de simular funciones también.
Enzyme está diseñado para probar componentes y es una excelente manera de escribir afirmaciones (o escenarios) que simulan acciones que confirman que la interfaz de usuario del front-end funciona correctamente. En otras palabras, busca componentes en el front-end, interactúa con ellos y levanta una bandera si alguno de los componentes no funciona como se le dijo que debería.
Entonces, Jest y Enzyme son herramientas distintas, pero se complementan bien entre sí.
Para nuestros propósitos, crearemos un nuevo proyecto React usando create-react-app porque viene con Jest configurado de inmediato.
yarn create react-app my-app
Todavía tenemos que instalar enzyme
y enzyme-adapter-react-16
(ese número debe basarse en la versión de React que esté usando).
yarn add enzyme enzyme-adapter-react-16 --dev
Bien, eso crea nuestro proyecto y nos pone tanto Jest como Enzyme en nuestro proyecto en dos comandos. A continuación, necesitamos crear un archivo de configuración para nuestras pruebas. Llamaremos a este archivo setupTests.js
y colóquelo en el src
carpeta del proyecto.
Esto es lo que debería estar en ese archivo:
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
Esto trae Enzyme y configura el adaptador para ejecutar nuestras pruebas.
Para facilitarnos las cosas, vamos a escribir pruebas para una aplicación React que ya he creado. Toma una copia de la aplicación en GitHub.
Toma de instantáneas de las pruebas
La prueba de instantáneas se utiliza para realizar un seguimiento de los cambios en la interfaz de usuario de la aplicación. Si se pregunta si estamos tratando con imágenes literales de la interfaz de usuario, la respuesta es no, pero las instantáneas son muy útiles porque capturan el código de un componente en un momento en el tiempo para que podamos comparar el componente en un estado versus cualquier otro estado posible que pudiera tomar.
La primera vez que se ejecuta una prueba, se crea una instantánea del código del componente y se guarda en una nueva __snapshots__
carpeta en el src
directorio. En las ejecuciones de prueba, la interfaz de usuario actual se compara con la existente. Aquí hay una instantánea de una prueba exitosa del componente de aplicación del proyecto de muestra.
it("renders correctly", () => {
const wrapper = shallow(
<App />
);
expect(wrapper).toMatchSnapshot();
});
Ahora, ejecuta la prueba:
yarn run test
Cada nueva instantánea que se genere cuando se ejecuta el conjunto de pruebas se guardará en el __tests__
carpeta. Lo bueno de que Jest verificará si el componente coincide en las ocasiones posteriores cuando ejecutemos la prueba, Jest verificará si el componente coincide con la instantánea en las pruebas posteriores. Así es como se ven esos archivos.
Creemos unas condiciones en las que la prueba falle. Cambiaremos el <h2>
etiqueta de nuestro componente de <h2>Random User</h2>
a <h2>CSSTricks Tests</h2>
y esto es lo que obtenemos en la línea de comando cuando se ejecutan las pruebas:
Si queremos que nuestro cambio pase la prueba, cambiamos el encabezado a lo que era antes o podemos actualizar el archivo de instantánea. Jest incluso proporciona instrucciones sobre cómo actualizar la instantánea directamente desde la línea de comandos, por lo que no es necesario actualizar la instantánea manualmente:
Inspect your code changes or press `u` to update them.
Entonces, eso es lo que haremos en este caso. Presionamos u
para actualizar la instantánea, pasa la prueba y seguimos adelante.
Atrapaste el shallow
método en nuestra instantánea de prueba? Eso es del paquete Enzyme y le indica a la prueba que ejecute un solo componente y nada más, ni siquiera los componentes secundarios que puedan estar dentro. Es una forma limpia y agradable de aislar código y obtener mejor información al depurar y es especialmente excelente para componentes simples y no interactivos.
Además de shallow
, también tenemos render
para pruebas de instantáneas. ¿Cuál es la diferencia, preguntas? Mientras shallow
excluye los componentes secundarios al probar un componente, render
los incluye mientras se procesa en HTML estático.
Hay un método más en la mezcla a tener en cuenta: mount
. Este es el tipo de prueba más atractivo del grupo porque procesa completamente los componentes (como shallow
y render
) y sus hijos (como render
) pero los coloca en el DOM, lo que significa que puede probar completamente cualquier componente que interactúe con la API DOM, así como cualquier accesorio que se le pase y reciba. Es una prueba completa de interactividad. También vale la pena señalar que, dado que realiza un montaje completo, querremos hacer una llamada a .unmount
en el componente después de que se ejecute la prueba para que no entre en conflicto con otras pruebas.
Prueba de los métodos del ciclo de vida de los componentes
Los métodos de ciclo de vida son ganchos proporcionados por React, que se llaman en diferentes etapas de la vida útil de un componente. Estos métodos son útiles cuando se manejan cosas como llamadas a API.
Dado que se utilizan a menudo en los componentes de React, puede hacer que su conjunto de pruebas los cubra para asegurarse de que todo funcione como se espera.
Hacemos la obtención de datos de la API cuando se monta el componente. Podemos comprobar si se llama al método del ciclo de vida haciendo uso de jest, lo que nos permite simular los métodos del ciclo de vida utilizados en las aplicaciones React.
it('calls componentDidMount', () => {
jest.spyOn(App.prototype, 'componentDidMount')
const wrapper = shallow(<App />)
expect(App.prototype.componentDidMount.mock.calls.length).toBe(1)
})
Adjuntamos espía al prototipo del componente y el espía al componentDidMount()
método de ciclo de vida del componente. A continuación, afirmamos que el método del ciclo de vida se llama una vez comprobando la duración de la llamada.
Probar accesorios de componentes
¿Cómo puede estar seguro de que los accesorios de un componente se pasan a otro? Tenemos una prueba para confirmarlo, ¡por supuesto! La API de Enzyme nos permite crear una función “simulada” para que las pruebas puedan simular el paso de accesorios entre componentes.
Digamos que estamos pasando accesorios de usuario del componente principal de la aplicación a un componente de perfil. En otras palabras, queremos que la aplicación informe al perfil con detalles sobre la información del usuario para representar un perfil para ese usuario.
Primero, burlémonos de los accesorios del usuario:
const user = {
name: 'John Doe',
email: '[email protected]',
username: 'johndoe',
image: null
}
Las funciones simuladas se parecen mucho a otras pruebas en el sentido de que están envueltas alrededor de los componentes. Sin embargo, estamos usando un adicional describe
capa que toma el componente que se está probando, luego nos permite continuar diciéndole a la prueba los accesorios y valores esperados que esperamos que se pasen.
describe ('<Profile />', () => {
it ('contains h4', () => {
const wrapper = mount(<Profile user={user} />)
const value = wrapper.find('h4').text()
expect(value).toEqual('John Doe')
})
it ('accepts user props', () => {
const wrapper = mount(<Profile user={user} />);
expect(wrapper.props().user).toEqual(user)
})
})
Este ejemplo en particular contiene dos pruebas. En la primera prueba, pasamos los accesorios del usuario al componente de perfil montado. Luego, verificamos si podemos encontrar un <h4>
elemento que corresponde a lo que tenemos en el componente Perfil.
En la segunda prueba, queremos comprobar si los accesorios que pasamos al componente montado son iguales a los accesorios simulados que creamos anteriormente. Tenga en cuenta que, aunque estamos destruyendo los accesorios en el componente Perfil, no afecta la prueba.
Simulacros de llamadas a la API
Hay una parte del proyecto que hemos estado usando en la que se realiza una llamada a la API para obtener una lista de usuarios. ¿Y adivina qué? ¡También podemos probar esa llamada a la API!
Lo un poco complicado de probar las llamadas a la API es que en realidad no queremos acceder a la API. Algunas API tienen límites de llamadas o incluso costos para realizar llamadas, por lo que queremos evitar eso. Afortunadamente, podemos usar Jest para simular solicitudes de axios. Consulte esta publicación para obtener un tutorial más completo sobre el uso de axios para realizar llamadas a la API.
Primero, crearemos una nueva carpeta llamada __mock__
en el mismo directorio donde nuestro __tests__
carpeta vive. Aquí es donde se crearán nuestros archivos de solicitud simulada cuando se ejecuten las pruebas.
module.exports = {
get: jest.fn(() => {
return Promise.resolve({
data: [
{
id: 1,
name: 'Jane Doe',
email: '[email protected]',
username: 'jdoe'
}
]
})
})
}
Queremos comprobar y ver que el GET
se hace la solicitud. Importaremos axios para eso:
import axios from 'axios';
Justo debajo de las declaraciones de importación, necesitamos que Jest reemplace axios con nuestro simulacro, por lo que agregamos esto:
jest.mock('axios')
La API de Jest tiene una spyOn()
método que toma un accessType?
argumento que se puede utilizar para comprobar si podemos “obtener” datos de una llamada a la API. Usamos jest.spyOn()
para llamar al método espiado, que implementamos en nuestro __mock__
archivo, y se puede utilizar con el shallow
, render
y mount
pruebas que cubrimos anteriormente.
it('fetches a list of users', () => {
const getSpy = jest.spyOn(axios, 'get')
const wrapper = shallow(
<App />
)
expect(getSpy).toBeCalled()
})
¡Pasamos la prueba!
Esa es una introducción al mundo de las pruebas en una aplicación React. Es de esperar que ahora vea el valor que las pruebas agregan a un proyecto y lo relativamente fácil que puede ser implementar, gracias al trabajo pesado realizado por los poderes conjuntos de Jest y Enzyme.
Otras lecturas
- Documentación de broma
- Documentación de enzimas
- Pruebas de instantáneas efectivas por Kent C. Dodds
- Probando React with Jest and Enzyme por Dominic Fraser