Más allá de React Testing Library: Pruebas en bibliotecas de React (y código similar a bibliotecas)

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

Cuando se trata de probar código de bibliotecas, el enfoque de la (generalmente increíble) "Testing Library" rápidamente alcanza sus limitaciones: A menudo necesitamos probar rutas de código activas para garantizar garantías adicionales, como un orden específico de cambios en el DOM o un número particular de renders.

En cuanto comenzamos a agregar Suspense a la imagen, incluso se vuelve casi filosófico:

- ¿Cómo contamos un renderizado que se suspende inmediatamente y cómo lo distinguimos de un renderizado "confirmado"?

- ¿Cómo sabemos qué partes del árbol de componentes se volvieron a renderizar?


En la base de código de Apollo Client, estamos utilizando el React Profiler para crear un flujo de eventos de renderizado, lo que nos permite cambiar a un método de prueba basado en streams.

Después de probar este enfoque internamente durante un año, lo hemos lanzado en una biblioteca que queremos presentar al mundo.

También echaré un vistazo breve a otros problemas "relacionados con las pruebas" que están muy fuera de lo normal que hemos encontrado y compartir nuestras soluciones:

Cómo probar bibliotecas que agrupan diferentes códigos para React Server Components, ejecuciones de SSR en streaming y el navegador: Pruebas de tus campos de `exports` cada vez más complejos y asegurando que todos esos entornos exporten la forma de paquete que esperas.

Incluso echaremos un vistazo breve a cómo renderizar componentes de React en diferentes entornos para probarlos de forma aislada, ya sea en Server Components, Streaming SSR o simulando la hidratación de streams en el navegador.

This talk has been presented at React Advanced 2024, check out the latest edition of this React Conference.

Lenz Weber-Tronic
Lenz Weber-Tronic
33 min
25 Oct, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
La charla de hoy se llama Más allá de React Testing Library, Pruebas en bibliotecas de React y código similar a bibliotecas. El orador, Lenz Liebertronik, analiza los requisitos especiales para probar bibliotecas, incluyendo minimizar los re-renderizados, evitar desgarros y renderizar componentes de forma granular. Destacan escenarios en los que React Testing Library se queda corto e introducen el flujo de renderizado de Testing Library React como solución. El orador demuestra cómo probar hooks, múltiples hooks y afirmar re-renderizados utilizando diferentes técnicas. Advierten sobre posibles problemas con las actualizaciones de React, componentes solo para pruebas, la agrupación ACT y los límites de Suspense. El orador comparte el uso del mundo real de la biblioteca de flujo de renderizado y analiza las limitaciones de correlacionar los renderizados con las confirmaciones del DOM. Enfatizan la importancia de probar bibliotecas y optimizar gradualmente el código. También mencionan los beneficios de usar la biblioteca de pruebas y concluyen con gratitud y una lección de holandés.

1. Introduction to Beyond Testing Library

Short description:

La charla de hoy se llama Beyond Testing Library, Testing React Libraries and Library-like Code. Soy Lenz Liebertronik, un mantenedor de Apollo Client en Apollo GraphQL. También soy el autor de RTKQuery y co-mantenedor de Redux Toolkit. He escrito muchas bibliotecas que ahora tengo que mantener. React Testing Library es excelente para las pruebas, pero no maneja bien la consistencia eventual, lo cual es importante al optimizar el rendimiento en las bibliotecas. Hablemos de los requisitos especiales que tengo para las pruebas.

Hola a todos. Hoy mi charla se llama Beyond Testing Library, Testing React Libraries and Library-like Code.

Solo un poco sobre mí. Lenz Liebertronik. Trabajo en Apollo GraphQL donde soy mantenedor de Apollo Client. También soy el autor de RTKQuery, co-mantenedor de Redux Toolkit, y debido a mi TDAH he escrito demasiadas bibliotecas que ahora tengo que mantener. Puedes encontrarme en GitHub y prácticamente en todas partes como Fryneas, excepto en Twitter, donde solo me llamo Fry. El nombre estaba libre. Son cuatro letras, así que tomé ese.

Generalmente necesitamos ver cómo llegué a esta charla y he estado escribiendo muchas pruebas para nuestras bases de código y generalmente me encanta usar React Testing Library para eso. Y es absolutamente increíble. Pero hay un pero en React Testing Library porque React Testing Library prueba lo que me gusta llamar consistencia eventual. Pero por otro lado, cuando escribo una biblioteca, necesito optimizar para un camino de código caliente porque la biblioteca que estoy escribiendo y que estás usando debería tener el menor impacto en el rendimiento de tu aplicación. Si hago un renderizado adicional en mi biblioteca, eso significa que mil aplicaciones por ahí también tienen ese renderizado adicional. Así que necesito probar eso y tengo un montón de requisitos especiales que necesito probar así que vamos a repasarlos.

Read also

2. Special Requirements for Testing Libraries

Short description:

Nuestro primer requisito es minimizar los re-renderizados innecesarios en los componentes que usan la biblioteca. Otro requisito es evitar el tearing, asegurando resultados consistentes de los hooks que acceden a la misma fuente de datos. También buscamos renderizar los componentes de la manera más granular posible, en el momento adecuado. Vamos a explorar un ejemplo de un hook probado con React Testing Library, que destaca escenarios más allá del mejor caso.

Nuestro primer requisito especial es lo que ya mencioné. Quiero asegurarme de que los componentes que usan mi biblioteca no se re-rendericen más de lo absolutamente necesario. El segundo requisito es una gran preocupación en React en general y es que no quieres tearing. No quieres que un solo hook devuelva un resultado inconsistente, pero también si usas dos hooks diferentes en el mismo componente que tal vez miran la misma fuente de datos, también deberían mirar la misma fuente de datos al mismo tiempo. Y lo mismo también en múltiples componentes. Si usas el mismo hook o diferentes hooks en toda tu aplicación en diferentes lugares, tienen que al mismo tiempo siempre devolverte los mismos datos, lo cual no siempre es fácil. Y luego esto vuelve al primero, pero un poco más especializado. Quiero renderizar no solo la menor cantidad de veces posible, sino también de la manera más granular posible. Solo el componente correcto en el momento correcto. Entonces, ¿por qué digo que necesitamos ir más allá de testing library para esto? Veamos un ejemplo de un hook simple probado con React Testing Library. Aquí tenemos un hook usequery que devuelve un objeto que tiene un estado de carga y una propiedad de datos en él. Y realmente el mejor escenario es lo que ves en la parte inferior. Primero tienes loading true y data undefined, y eso va directamente al estado final, loading false y data hello world. Y eso pasaría esta prueba. Esta prueba prueba de manera sincrónica que loading sea true y que data sea undefined. Luego espera un tiempo hasta que loading es false. Y luego probamos que data es hello world. Pero hay muchos más escenarios que solo este mejor caso que realmente pasan esta prueba.

3. Testing Library Scenarios

Short description:

El primer escenario involucra renderizados adicionales causados por acciones no relacionadas en un hook. Otro problema es la inconsistencia en los estados de data y loading durante diferentes renderizados. También hay un caso de uso específico donde una prueba inestable puede pasar debido a problemas de sincronización con promesas. Estos escenarios pueden introducir problemas que buscamos evitar. En una aplicación normal, TypeScript puede ayudar a prevenir tales problemas y asegurar una experiencia de usuario fluida.

El primero de esos escenarios es algo no relacionado en ese hook hace algo que no es producido por el hook, pero nos cuesta renderizados adicionales. Y estos renderizados no aparecerían en esta prueba. Y no tendría ninguna manera de probar eso o de asegurarme de que eso no se cuele en la biblioteca después del hecho.

También hay otras cosas que pueden salir mal. Por ejemplo, data y loading pueden cambiar en diferentes renderizados. Así que tenemos este renderizado intermedio donde loading sigue siendo true. Y data ya pasa a hello world. Y eso es lo que quise decir con tearing antes, tearing dentro de un hook. Queremos evitar eso en cualquier momento. Pero esta prueba no lo evitará porque probamos que loading sea false primero, y luego probamos data. Pero data no se prueba entre este data para ser undefined y loading para ser false. Así que en realidad podría tomar cualquier forma en el medio. Y de hecho también hasta que loading sea false, loading también podría tomar cualquier forma. Así que sí, esto pasaría esta prueba.

Y luego hay incluso un caso de uso realmente extraño y específico. Con el tiempo adecuado, esto puede pasar. Será una prueba inestable, pero puede pasar. Veamos por qué esto puede pasar. Porque parece que si miras la prueba, esto no debería pasar. Pero el problema es que waitFor() crea una promesa. E incluso después de que esta afirmación de loading para ser false tenga éxito, esa promesa aún tiene que ser esperada. Así que hay un solo tick en el medio. En qué momento React podría comenzar a renderizar contra algo más. Así que necesitarías escribir una prueba muy específica, y no siempre tendría éxito. Pero esto añadiría una prueba inestable a tu base de código. Y es algo que quiero evitar a toda costa.

Así que todo lo que has visto hasta ahora está bien en una aplicación normal. Esperemos que uses TypeScript, que evitará situaciones completamente incorrectas en tu código, y también detectaría ese estado de loading puppy. Y tu UI eventualmente llegará a ese estado objetivo, y el usuario solo verá un breve parpadeo o algo así. Es algo así como aceptable.

4. Testing Library Challenges

Short description:

Probar bibliotecas en aplicaciones y las bibliotecas en sí mismas requieren diferentes enfoques de prueba. El componente React Profiler proporciona una solución al permitir que se tomen instantáneas de los valores renderizados. Sin embargo, no es intuitivo de usar en cada prueba. Para abordar esto, se ha introducido una nueva biblioteca de pruebas llamada Testing Library React render stream. Esta biblioteca está diseñada específicamente para probar piezas importantes, como bibliotecas, utilizando un enfoque de renderizado por renderizado.

Pero solo está bien en una aplicación. No está bien en una biblioteca. Porque, por un lado, tenemos este error, y mil aplicaciones por ahí tienen ese error. Y la otra cosa es que no agregas una sola biblioteca. Agregas unas pocas docenas de bibliotecas. Así que si cada biblioteca solo trae un error a tu aplicación, no has escrito una sola línea de código tú mismo, y ya tienes una docena de errores en tu aplicación. Así que como biblioteca, necesitamos probar de manera diferente, y necesitamos probar con más precisión.

Lo mismo no solo se aplica a nosotros, los autores de bibliotecas, por cierto. También se aplica a esa biblioteca interna que tienes en tu empresa que es compartida por diez equipos, y una persona la mantiene. También se aplica a la ruta de código absolutamente crítica que tienes en tu aplicación, si solo tienes una aplicación. Este es como el código que se llama en todas partes y necesita ser optimizado. Así que probamos muchas cosas diferentes para contar renderizados y hacer afirmaciones mientras se renderiza, y algunas de ellas funcionaron por un tiempo. Algunas se rompieron cuando cambiamos de React 16 a 17 y 18. Otras se rompieron en el momento en que añadimos suspense a la imagen.

Hubo una solución al final que realmente se mantuvo y funcionó, y fue usar el componente React Profiler porque este componente React Profiler, si ampliamos, tiene este callback on-render y cada vez que un renderizado termina, se llama a este callback, y puedo sincrónicamente tomar una instantánea de todos los valores que me interesan. Así que tomo esa instantánea, simplemente la empujo a un array, y dejo que mi aplicación se ejecute. No hago ninguna afirmación, y después de un tiempo, simplemente miro el array de instantáneas aquí y me aseguro de que haya ese primer renderizado donde tenemos true y undefined, y luego el segundo renderizado es false y hello world, y que después, esperamos otros cien milisegundos y no llega un tercer renderizado. El problema con esto es que realmente no es intuitivo de usar. Marca muchas de las casillas que teníamos antes, pero no quieres escribir esto en cada prueba. Pero está esa cosa de que soy un autor de bibliotecas y sé cómo construir una biblioteca, así que eso es esencialmente lo que hice o lo que hicimos.

Así que la siguiente diapositiva es un problema. El título de esta charla es Beyond Testing Library, y cuando lanzamos eso la semana pasada, se convirtió en parte de Testing Library. Así que con esta charla, estoy presentando el Testing Library React render stream, que es una biblioteca de pruebas basada en este profiler que acabamos de ver para probar un paso de código crítico render por render, y no puedo enfatizar esto lo suficiente. Esto no es lo que normalmente deberías usar para probar toda tu aplicación. Esto es para probar las piezas importantes, y la mayoría de las veces, esas piezas importantes son una biblioteca.

Veamos eso. Tenemos la prueba de antes, y vamos a reescribirla para alejarnos de esa cosa del profiler terriblemente confusa. Primero, vamos a reemplazar toda esa lógica de renderizado de antes, y usamos esta API llamada Create Render Stream, que nos devuelve un objeto que tiene algunas propiedades. Una de ellas es Replay Snapshot, y otra es Render. Primero creamos un componente hook, en el cual llamamos a nuestro hook, y el resultado de eso lo ponemos inmediatamente en Replay Snapshot.

5. Testing Library Render and Snapshot

Short description:

Llamamos a Render con el componente hook. Tomamos otra cosa del render stream, la función Take Render. Afirmamos los valores de loading y data después del primer y segundo renderizado. Podemos configurar el tiempo de espera para la prueba. Usamos render hook para snapshot stream para el componente hook. Podemos asegurar que el componente no se vuelva a renderizar más de lo necesario y verificar la consistencia. Hay un caso de un hook y dos componentes diferentes que desencadenan actualizaciones en hooks con diferente comportamiento de tiempo en React 18.

Y luego llamamos a Render con ese componente hook. Render es el mismo render al que estás acostumbrado de React Testing Library. Solo agrega algunos envoltorios y hace algunas cosas más, pero esencialmente llama a lo mismo cosa. Luego reescribimos esos casos de prueba allí abajo. Tomamos otra cosa del render stream, que es esta función Take Render. Por cierto, este es un truco súper ingenioso. Si usas estos bloques solitarios, puedes reutilizar el mismo nombre de variable cada vez, y también te aseguras de que no salga del alcance. Así que puedo usar el nombre snapshot para una variable aquí y el nombre snapshot para una variable aquí, y no tengo snapshot1, snapshot2 y snapshot25, porque ¿quién quiere hacer eso? Esencialmente, tomamos el primer renderizado, y esperamos tomar el primer renderizado, lo que significa que el renderizado ya podría haber ocurrido, o ocurrirá en el futuro. Y luego esperamos hasta que suceda, y luego lo miramos. Y afirmamos que loading es true y data es undefined. Y luego tomamos o esperamos y tomamos el segundo renderizado, y afirmamos que loading es false y data es Hello, world! Todavía tenemos esa cosa extraña de resultados de promesa, prueba de longitud de set timeout allí abajo, y también podemos escribir eso de manera más agradable. Solo decimos await expect take render, no volver a renderizar. Esto es como un tiempo de espera predeterminado de, creo, 100 milisegundos, pero también podrías configurarlo si quisieras esperar más tiempo o si quieres que la prueba sea más rápida y tener algo de confianza en tu código. Por supuesto, todavía tenemos ese componente hook allí arriba y donde nuestra React testing library tiene la función render y la función render hook, en lugar de create render stream, solo tenemos render hook to snapshot stream, donde pones tu hook allí arriba, y solo obtienes un método take snapshot de vuelta. Y luego puedes simplemente mirar todas las instantáneas que fueron creadas desde el hook. Cada vez que ese hook causa un nuevo renderizado, se toma una nueva instantánea y podemos avanzar a través de ellas pieza por pieza por pieza.

Así que, miremos hacia atrás a esos requisitos de antes. ¿Cuáles de esos ya estamos cumpliendo? Podemos asegurar que el componente no se vuelva a renderizar más de lo necesario. Hicimos eso. Podemos verificar esta consistencia dentro de una llamada de hook. También podemos hacerlo en un componente porque, como el ejemplo de dos diapositivas antes era un componente, no una llamada de hook per se. Podríamos hacer más allí. Todavía tenemos esa pregunta, como un hook y dos componentes diferentes. Así que miremos ese caso a continuación. Miremos eso por un segundo, por qué es importante hacer eso. Puedes tener una fuente de datos, pero dos formas diferentes de desencadenar actualizaciones en tus hooks. Hay un useState para desencadenar una actualización en un nuevo renderizado de componente. Hay useSyncExternalStore. Y hasta React 18, esos tenían un comportamiento de tiempo diferente. React 18 los agruparía, pero agruparía todos los useStates juntos, y agruparía todos los useSyncExternalStores juntos, pero aún así terminarían en dos renderizados diferentes.

6. Testing Multiple Hooks and Granular Re-rendering

Short description:

Probamos dos hooks diferentes, useQuery y useFragment. Fusionamos los resultados en el snapshot usando mergeSnapshot. Renderizamos ambos componentes uno al lado del otro, hacemos afirmaciones sobre los resultados y aseguramos que no ocurra un re-renderizado. Esto nos permite probar múltiples componentes y lograr un re-renderizado granular usando suspense.

Así que si tienes un hook que usa una de las APIs y otro hook que usa la otra API, todavía obtendrías como un renderizado donde las cosas son un poco extrañas. Así que aquí voy a probar dos hooks diferentes que en realidad tenían esas dos implementaciones diferentes en algún momento en Apollo Client, useQuery y useFragment. Y esencialmente no estoy tomando como un snapshot con un hook, sino que estoy poniendo dos propiedades en mi snapshot, como el último resultado de useQuery que vimos y el último resultado de useFragment que vimos. Y tampoco estoy usando replaySnapshot aquí, sino que voy a usar mergeSnapshot.

Y si vemos cómo usamos eso, creamos dos componentes que renderizamos uno al lado del otro. También podríamos hacer ambos en un componente, pero esto es como un poco más separado de cada uno, lo que hace una prueba más agradable. Y en uno de esos componentes, fusionamos el resultado de useQuery en el snapshot, y en el otro componente fusionamos el resultado de useFragment en el snapshot. Renderizamos ambos componentes uno al lado del otro, y luego miramos esos snapshots, hacemos un takeRender, sacamos el snapshot del renderizado, hacemos nuestra afirmación sobre el resultado de useQuery, y hacemos la afirmación sobre el resultado de useFragment. Lo repetimos por segunda vez, y ahora sabemos que definitivamente ambos hooks se renderizaron al mismo tiempo con el mismo contenido, y al final verificamos nuevamente que no volvemos a renderizar otra vez.

Así que volviendo a los requisitos especiales, ahora podemos hacer esto sobre múltiples componentes, lo cual es importante. La última cosa es ese re-renderizado granular. Quiero saber qué componente se vuelve a renderizar, si vuelvo a renderizar un árbol completo. Y para eso, veamos qué desencadenó este requisito especial, que fue suspense. Porque aquí tenemos un componente de carga que muestra un estado de carga, tenemos un componente de error que muestra un estado de error, tenemos nuestro propio componente que llama a useSuspenseQuery y simplemente obtiene datos de vuelta, y luego tenemos una aplicación que junta todo con un suspense boundary con un fallback con un error boundary con un fallback con un componente. Por el bien de que las diapositivas no exploten, ignoramos el estado de error por ahora, y luego realmente miramos cómo construir un caso de prueba con esto.

7. Different Ways to Test and Assert Re-renders

Short description:

Vemos tres formas diferentes de probar. Primero, tomamos un snapshot de los datos y lo añadimos a un componente. Luego miramos el DOM real usando la opción snapshot DOM. Finalmente, reescribimos componentes y usamos el hook useTrackRenders para afirmar re-renderizados.

Así que ahora miramos estas tres formas diferentes. La primera es lo que ya sabes, que es tomar un snapshot de los datos, así que decimos replaySnapshot, y añadimos ese resultado de replaySnapshot a un componente al lado. Y luego en nuestra prueba podemos tomar renders, miramos los snapshots. El primer render es, con suerte, indefinido porque ese componente nunca se renderizó, porque todo lo que vemos es un estado de carga. En el segundo render, todo debería estar ya obtenido, los datos deberían estar allí, y nuestro snapshot debería ser reemplazado.

La segunda forma de ver esto, porque esto nos dio algo de información, pero no nos dio plena confianza de que todo está funcionando, es mirar el DOM real. Por cierto, ¿podrías pasarme un poco de agua, por favor? Gracias. Lo siento, es mucho hablar. Así que ahora queremos mirar el DOM. Y no solo tomamos snapshots normales con esa cosa de replaySnapshot, también tenemos una opción de snapshot DOM. Y esto está desactivado por defecto, puedes activarlo. Significa que cada vez que ocurre un render, se toma un snapshot completo del DOM en ese momento y se crea una copia completa de tu DOM. Esto no es gratis. Eso significa que necesitas optar por ello. Ocupa más memoria, probablemente también ralentiza un poco tu prueba, así que úsalo con moderación.

Pero en este caso, tomamos el primer render y miramos el DOM del primer render usando esta cosa de withinDOM de ese snapshot. Y luego simplemente hacemos lo que haríamos si escribieras una prueba de React Testing Library. Simplemente usamos las afirmaciones normales de DOM de la biblioteca de pruebas. Así que withinDOM getByTextLoading nos da ese elemento DOM con un texto de carga. Afirmamos que eso está en el documento. Luego volvemos a renderizar. Luego afirmamos que esa misma cosa ya no está en el documento, pero que Hello ha sido renderizado porque ese es como el saludo que obtuvimos de los datos. Esas dos cosas ya son geniales, pero aún no podemos afirmar que ciertos re-renderizados no ocurren y cosas así.

Hay una tercera forma. Esta requiere que reescribamos nuestros componentes un poco más. Es un hook useTrackRenders que simplemente inyectamos en cada uno de esos componentes en la lista. Y luego podemos decir algo como expandRendersComponent para igualar estrictamente appLoadingComponent, lo que significa que en nuestro primer render, el componente de la aplicación se renderiza, el componente de carga se renderiza, pero el componente componente no se renderizó. Y luego tenemos ese segundo snapshot que tomamos. Y aquí miramos los componentes renderizados nuevamente. Vemos que la aplicación, como el componente padre, no se volvió a renderizar, pero el componente hijo sí lo hizo.

8. Cautions and Future Considerations

Short description:

Al combinar todas estas técnicas, podemos tener confianza en el código que enviamos. Sin embargo, hay algunas precauciones a considerar. Las actualizaciones de React pueden romper pruebas, se necesitan componentes solo para pruebas al usar ciertas características, y el ACT batching puede interferir con las pruebas de renderizado. Además, los límites de Suspense tienen un requisito de tiempo mínimo que puede afectar la duración de la prueba. Esperamos que el equipo de React aborde estos problemas en el futuro.

Así que el componente se renderizó. Y si juntas todo esto y volvemos a añadir el componente de error, esto es como una prueba completa. Y esta prueba me da confianza para enviar código que realmente hace lo que debe hacer y nada más.

Volviendo atrás, nuestro último requisito especial obtiene una marca de verificación. Todo esto suena bastante bien, pero quiero añadir un montón de palabras de precaución. Una que no necesito añadir yo mismo. Lanzamos esta biblioteca la semana pasada. La publicamos en Twitter. Así que dejemos que Andrew Clark tenga el escenario por un segundo. Él dice que ellos prueban React de manera similar, pero también solo para usar esto para bibliotecas o código similar a bibliotecas, porque existe la posibilidad de que React simplemente cambie cuando se renderiza. Así que si haces una actualización de React, podría romper la mitad de tus pruebas mientras que en realidad todo está bastante bien. Solo tienes que saber que esta nueva versión de React hace las cosas de manera diferente. Y tal vez te muestre algo. Tal vez no. Así que si haces esto en la prueba normal de tu aplicación, podrías entrar en pánico por algo que es simplemente de esperar. Deja ese dolor a los autores de bibliotecas. Algunas otras palabras de precaución, incluso para bibliotecas, este no siempre es un buen enfoque porque necesitas escribir tus propios componentes solo para pruebas porque tienes que inyectar esta cosa de Replay Snapshot en tu componente. Tienes que inyectar incluso algo que podría ir como una prop, pero lo que no podría ir como una prop es esa cosa de use track renders.

Pero para la cosa de use track renders, en realidad hay como un poco de esperanza en el horizonte, que es algo descubierto por Ken C. Dots hace unas semanas, quien encontró una manera de inyectar las herramientas de desarrollo de React en su código de usuario para usar la lógica que hace que estos marcos parpadeen cuando obtienes un re-renderizado para detectar qué componentes se estaban re-renderizando en qué momento. Así que estoy deseando usar eso en algún momento, pero probablemente siempre será una característica experimental porque no hay garantías sobre eso. Una última advertencia, todos estamos acostumbrados a escribir pruebas de componentes con ACT en todas partes sin realmente saber qué hace ACT. Al menos yo no lo sabía, y no se menciona en ninguna parte de la documentación excepto que deberías usarlo. Y resulta que ACT agrupa los renders juntos, lo cual es genial en una prueba normal, excepto si quieres probar cuándo ocurren los renders. Así que la idea aquí es no usar ACT, lo que añade algunos problemas adicionales. Los límites de Suspense en React siempre se muestran por un tiempo mínimo de 500 milisegundos. Así que nuestras pruebas de repente fueron 80 segundos más largas, pero solo en React 19 y React 18, está bien. Y queremos que el equipo de React haga eso configurable. Hay una discusión que ha estado estancada por demasiado tiempo y no está pasando nada allí. Así que actualmente estamos parcheando React para configurarlo nosotros mismos, pero con suerte en el futuro, esto ya no será necesario.

QnA

Real World Usage and Q&A

Short description:

La biblioteca React RenderStream se ha utilizado con éxito en 544 pruebas para Apollo Client, solucionando numerosas pruebas inestables. El orador comparte su experiencia de ejecutar un bucle infinito para identificar y corregir pruebas fallidas. Animan a la audiencia a probar la biblioteca y mencionan algunos errores tipográficos que se han corregido.

Y solo lo parcheamos para la prueba. Así que todo bien. El uso en el mundo real significa que usamos esto en 544 pruebas actualmente para Apollo Client. Hemos estado usando esto durante aproximadamente un año antes de lanzarlo públicamente, y realmente solucionó tantas pruebas inestables en nuestra base de código. Y en algún momento simplemente me molestaron las pruebas inestables. Así que hice un bucle infinito que siempre volvía a ejecutar nuestro conjunto de pruebas hasta que ya no fallaba. Y simplemente prueba por prueba por prueba que fallaba, porque teníamos pruebas que funcionaban bien 99 veces, pero fallaban la centésima donde el tiempo con la biblioteca de pruebas normal de React era simplemente incorrecto.

Dicho todo esto, has sido advertido, pero espero que también veas una especie de promesa en esto, así que ve pruébalo tú mismo. Está disponible en 1.0.3 o algo así. Así que ya tuvimos algunos errores tipográficos que corregir. Testing library slash React RenderStream. Y con eso, llegamos a la sesión de preguntas y respuestas.

Correlating Renders and React Internals

Short description:

El orador discute las limitaciones de correlacionar funciones de renderizado con commits al DOM, especialmente al usar características de React como suspense. Mencionan características futuras que pueden afectar la re-ejecución y el re-renderizado. El orador también responde a una pregunta sobre la biblioteca que depende de los internos de React, afirmando que proporciona una alternativa al acceso a los internos y menciona el uso de una biblioteca de React que suprime advertencias.

Mi primera pregunta es, escucho tu charla, y creo que esto es increíble. Se ve realmente bien. Soy un poco más tonto que tú, pero solo uso ends como ends render. Olvidé la cosa exacta. Podrías probar que se llama a un método. Sí, pero no renders. Y la cosa es que normalmente React llama al método una vez por render, dos veces si usas strict mode, y entre una y un millón de veces si usas suspense. El momento en que suspense entra en escena, simplemente ya no funciona tener esa correlación entre la función de renderizado que se ejecuta, y hay realmente un commit al DOM, que es lo que más nos preocupa. Y puedes medir cuántos componentes se re-ejecutan, pero todo lo demás podría influir en eso. Las próximas características de React como, hay una cosa fuera de pantalla próxima de la que estaban hablando, que probablemente afectaría muchas cosas. Cosas re-ejecutándose pero no necesariamente re-renderizándose pero tal vez re-renderizándose. Como esto me da confianza, solo contar un contador ya no lo hace y lo hará incluso menos en el futuro.

Bien, puedo entender eso. Gracias. Veamos qué ha estado preguntando la audiencia. La primera pregunta es de Ben Durant. ¿Esta biblioteca depende de algún interno espeluznante de React que me hará despedir? No. Hoy en día solo tienes que advertir a tus usuarios que no pueden actualizar. Así que has sido advertido. Pero sí, los internos de useTrackRender acceden a los internos de React para averiguar de qué componente lo estás llamando. Pero si no quieres eso, también puedes simplemente darle un argumento de cadena y ese argumento de cadena se usa en su lugar. Y eso ya no accederá a ningún interno de React. Todavía no estás usando la biblioteca normal de React como dependencia para esto, sino la biblioteca de React, que también mantengo, que simplemente suprime todas las advertencias. Si accedes a los internos, porque creo que no deberíamos, pero aún está bien y es agradable hacerlo a veces. No deberíamos, pero aún está bien. Esa es una oración. Sí. Justo. No, puedo vivir con eso. Sí.

Testing Confidence and Duration

Short description:

El orador discute la confianza y advierte sobre sus declaraciones. Responden a una pregunta sobre la duración y frecuencia de ejecución de pruebas en el cliente Apollo. Se plantea otra pregunta sobre la dependencia de las pruebas en detalles de implementación, a lo que el orador responde positivamente.

Como dije en el escenario, está bien, pero también advierto a la gente. ¿Verdad? Hice mi parte. Sí. Es una advertencia justa. Sí. No. ¿Alguien siente que es bueno lo que está diciendo allí? ¿O están asustados? ¿Alguien más confiado ahora? Muy bien.

La siguiente pregunta es de nuestro valioso miembro de la audiencia, Anónimo. ¿Cuánto tiempo tardan en ejecutarse las 544 pruebas en el cliente Apollo y cuándo se ejecutan? Son parte de un conjunto de pruebas mucho más grande, que creo que es de alrededor de 2,500. En CI eso toma alrededor de cinco minutos porque todavía estamos en test, lo cual honestamente todavía me gusta y no me importan esos cinco minutos. Me apuntaría a cinco minutos. No te preocupes. Oh, está bien. O las ejecutas localmente, lo que significa que son como unos pocos segundos. Así que está perfectamente bien. En cada pull request, en cada commit a cualquier rama en los repositorios del cliente Apollo. Así que bastante a menudo. Genial. Genial.

Porque ¿cuántas personas están trabajando en eso? Somos como tres colaboradores principales y es de código abierto. Mucha gente simplemente contribuye. Sí. Así que al menos unas pocas veces al día.

Testing Libraries and Implementation Details

Short description:

El orador discute la dependencia de las pruebas en detalles de implementación cuando se trata de bibliotecas. Explican la diferencia entre probar bibliotecas y aplicaciones, enfatizando la necesidad de garantías más estrictas en las pruebas de bibliotecas. El orador también comparte una estrategia de agregar y eliminar gradualmente renders para optimizar el código. Finalmente, mencionan que escribir pruebas se ha vuelto más agradable.

Sí. {{^}}Sí. Genial.

La siguiente pregunta es de Matthew F. Siento que esta forma de probar a menudo puede depender de detalles de implementación. ¿Cuál es tu opinión al respecto? Sí. Está bien. Sí. Eso está perfectamente bien. Si escribo una biblioteca, quiero garantizar ciertos detalles de implementación. Esa es la diferencia entre probar una biblioteca y probar una aplicación. En una aplicación, pruebo para la consistencia eventual, pruebo que la interfaz de usuario llegue a donde debe estar. Pero si escribo una biblioteca, necesito hacer garantías mucho más estrictas. Y por eso digo que esto es genial para bibliotecas. Esto es genial para ese camino de código súper caliente, como ese hook que llamas en cada segundo componente de tu aplicación. Quieres probar un detalle de implementación allí, simplemente no en ningún otro lugar. Porque ese render adicional se suma con cada otro render adicional. Y si puedes tener un lugar en tu base de código que optimices, y al final eliminas 500 renders adicionales como resultado, eso es increíble y es una victoria. Pero lo que a veces hago es simplemente agregar esos 500 renders, y luego eliminarlos una semana después y decirle a mi jefe, mira lo que hice, lo hice mucho más rápido. Puedes. No le digas a nadie, MadHead. Mis colegas en la audiencia, no le digan a nadie. Si escribes esa prueba, también puedes simplemente tomar algunos renders más en el medio y eliminarlos con el tiempo. Sí. Oh sí, como mejorado gradualmente. Bonito. Correcto.

Siguiente pregunta. Realmente no hago eso. TK está preguntando, ¿ha hecho esto que escribir pruebas sea más agradable? Mucho más.

Benefits of Testing Library and Dutch Lesson

Short description:

El orador discute los beneficios de usar la testing library, expresando cómo les proporciona la confianza que necesitan para sus pruebas. Enfatizan la importancia de no renderizar directamente el componente y, en su lugar, recomiendan escribir un componente específico para pruebas alrededor de él. Además, mencionan el uso de snapshots de DOM para probar los internos del componente y las limitaciones de la testing library. Finalmente, el orador concluye la sesión con gratitud y una divertida lección de holandés.

Sí. Honestamente, se siente mucho mejor para las pruebas que estamos haciendo y necesitamos hacer, porque nos da exactamente la confianza que necesitamos y que no podíamos obtener antes. Era literalmente imposible, o con una cosa de profiler, no quieres escribir eso dos veces en toda tu vida. Genial. Entonces tal vez una, tal vez dos más.

Anónimo hace otra pregunta. Si es demasiado complejo escribir un componente específico para pruebas, ¿cómo evito enviar renderizadores usados en mi componente, ya que solo es relevante en pruebas? Es por eso que probablemente no quieras renderizar directamente tu componente, sino que escribas un componente específico para pruebas alrededor de él. No puedes evitar eso. No veo una forma de evitar eso. Sí, así que tendré un componente de contador y luego un componente de renderizado de prueba de contador que solo agrega los renderizadores usados. Bueno, realísticamente, si escribes una aplicación, o si escribes una prueba, mejor, probablemente escribas un poco de cosa JSX de todos modos, y ahí es donde harías eso. Lo veo un poco más difícil si tienes internos de un componente. Probablemente no puedas probar esos con esto. Irías por snapshots de DOM y solo lo mirarías desde afuera, cómo cambia el DOM, y aún obtienes la información sobre cuántos renders tienes, pero no sabes qué parte de tu detalle de implementación se renderizó cuándo, y eso está bien. Probablemente no puedas hacer todo con esto, pero es una gran caja de herramientas para hacer algunas cosas.

Muy bien. Supongo que eso es todo el tiempo que tenemos. Una pequeña lección de holandés, porque dijiste algo que me parece gracioso. DOM es la palabra holandesa para tonto. Así que para mí, siempre leo snapshot de DOM. Súper divertido. Eso es todo el tiempo que tenemos. Así que, Lens, muchas gracias. Gracias por invitarme.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Solicitudes de Red con Cypress
TestJS Summit 2021TestJS Summit 2021
33 min
Solicitudes de Red con Cypress
Top Content
Cecilia Martinez, a technical account manager at Cypress, discusses network requests in Cypress and demonstrates commands like cydot request and SCI.INTERCEPT. She also explains dynamic matching and aliasing, network stubbing, and the pros and cons of using real server responses versus stubbing. The talk covers logging request responses, testing front-end and backend API, handling list length and DOM traversal, lazy loading, and provides resources for beginners to learn Cypress.
Pruebas de ciclo completo con Cypress
TestJS Summit 2022TestJS Summit 2022
27 min
Pruebas de ciclo completo con Cypress
Top Content
Cypress is a powerful tool for end-to-end testing and API testing. It provides instant feedback on test errors and allows tests to be run inside the browser. Cypress enables testing at both the application and network layers, making it easier to reach different edge cases. With features like AppActions and component testing, Cypress allows for comprehensive testing of individual components and the entire application. Join the workshops to learn more about full circle testing with Cypress.
Desarrollo Efectivo de Pruebas
TestJS Summit 2021TestJS Summit 2021
31 min
Desarrollo Efectivo de Pruebas
Top Content
This Talk introduces Test Effective Development, a new approach to testing that aims to make companies more cost-effective. The speaker shares their personal journey of improving code quality and reducing bugs through smarter testing strategies. They discuss the importance of finding a balance between testing confidence and efficiency and introduce the concepts of isolated and integrated testing. The speaker also suggests different testing strategies based on the size of the application and emphasizes the need to choose cost-effective testing approaches based on the specific project requirements.
Playwright Test Runner
TestJS Summit 2021TestJS Summit 2021
25 min
Playwright Test Runner
Top Content
The Playwright Test Runner is a cross-browser web testing framework that allows you to write tests using just a few lines of code. It supports features like parallel test execution, device emulation, and different reporters for customized output. Code-Gen is a new feature that generates code to interact with web pages. Playwright Tracing provides a powerful tool for debugging and analyzing test actions, with the ability to explore trace files using TraceViewer. Overall, Playwright Test offers installation, test authoring, debugging, and post-mortem debugging capabilities.
Todos pueden escribir pruebas fácilmente
TestJS Summit 2023TestJS Summit 2023
21 min
Todos pueden escribir pruebas fácilmente
Playwright is a reliable end-to-end testing tool for modern web apps that provides one API, full isolation, fast execution, and supports multiple languages. It offers features like auto-weighting, retrying assertions, seamless testing of iframes and shadow DOM, test isolation, parallelism, and scalability. Playwright provides tools like VS Code extension, UiMode, and Trace Viewer for writing, debugging, and running tests. Effective tests prioritize user-facing attributes, use playwright locators and assertions, and avoid testing third-party dependencies. Playwright simplifies testing by generating tests, providing code generation and UI mode, and allows for easy running and debugging of tests. It helps in fixing failed tests and analyzing DOM changes, fixing locator mismatches, and scaling tests. Playwright is open source, free, and continuously growing.

Workshops on related topic

Diseñando Pruebas Efectivas con la Biblioteca de Pruebas de React
React Summit 2023React Summit 2023
151 min
Diseñando Pruebas Efectivas con la Biblioteca de Pruebas de React
Top Content
Featured Workshop
Josh Justice
Josh Justice
La Biblioteca de Pruebas de React es un gran marco para las pruebas de componentes de React porque responde muchas preguntas por ti, por lo que no necesitas preocuparte por esas preguntas. Pero eso no significa que las pruebas sean fáciles. Todavía hay muchas preguntas que tienes que resolver por ti mismo: ¿Cuántas pruebas de componentes debes escribir vs pruebas de extremo a extremo o pruebas de unidad de nivel inferior? ¿Cómo puedes probar una cierta línea de código que es difícil de probar? ¿Y qué se supone que debes hacer con esa persistente advertencia de act()?
En esta masterclass de tres horas, presentaremos la Biblioteca de Pruebas de React junto con un modelo mental de cómo pensar en el diseño de tus pruebas de componentes. Este modelo mental te ayudará a ver cómo probar cada bit de lógica, si debes o no simular dependencias, y ayudará a mejorar el diseño de tus componentes. Te irás con las herramientas, técnicas y principios que necesitas para implementar pruebas de componentes de bajo costo y alto valor.
Tabla de contenidos- Los diferentes tipos de pruebas de aplicaciones de React, y dónde encajan las pruebas de componentes- Un modelo mental para pensar en las entradas y salidas de los componentes que pruebas- Opciones para seleccionar elementos DOM para verificar e interactuar con ellos- El valor de los mocks y por qué no deben evitarse- Los desafíos con la asincronía en las pruebas de RTL y cómo manejarlos
Requisitos previos- Familiaridad con la construcción de aplicaciones con React- Experiencia básica escribiendo pruebas automatizadas con Jest u otro marco de pruebas unitarias- No necesitas ninguna experiencia con la Biblioteca de Pruebas de React- Configuración de la máquina: Node LTS, Yarn
Detox 101: Cómo escribir pruebas de extremo a extremo estables para su aplicación React Native
React Summit 2022React Summit 2022
117 min
Detox 101: Cómo escribir pruebas de extremo a extremo estables para su aplicación React Native
Top Content
Workshop
Yevheniia Hlovatska
Yevheniia Hlovatska
A diferencia de las pruebas unitarias, las pruebas de extremo a extremo buscan interactuar con su aplicación tal como lo haría un usuario real. Y como todos sabemos, puede ser bastante desafiante. Especialmente cuando hablamos de aplicaciones móviles.
Las pruebas dependen de muchas condiciones y se consideran lentas e inestables. Por otro lado, las pruebas de extremo a extremo pueden dar la mayor confianza de que su aplicación está funcionando. Y si se hace correctamente, puede convertirse en una herramienta increíble para aumentar la velocidad del desarrollador.
Detox es un marco de pruebas de extremo a extremo en caja gris para aplicaciones móviles. Desarrollado por Wix para resolver el problema de la lentitud e inestabilidad y utilizado por React Native en sí como su herramienta de pruebas E2E.
Únete a mí en esta masterclass para aprender cómo hacer que tus pruebas de extremo a extremo móviles con Detox sean excelentes.
Prerrequisitos- iOS/Android: MacOS Catalina o más reciente- Solo Android: Linux- Instalar antes de la masterclass
Masterclass de Pruebas de API con Postman
TestJS Summit 2023TestJS Summit 2023
48 min
Masterclass de Pruebas de API con Postman
Top Content
WorkshopFree
Pooja Mistry
Pooja Mistry
En el panorama siempre en evolución del desarrollo de software, garantizar la fiabilidad y funcionalidad de las API se ha vuelto primordial. "Pruebas de API con Postman" es una masterclass completa diseñada para equipar a los participantes con los conocimientos y habilidades necesarios para sobresalir en las pruebas de API utilizando Postman, una herramienta poderosa ampliamente adoptada por profesionales en el campo. Esta masterclass profundiza en los fundamentos de las pruebas de API, avanza a técnicas de prueba avanzadas y explora la automatización, las pruebas de rendimiento y el soporte multiprotocolo, proporcionando a los asistentes una comprensión holística de las pruebas de API con Postman.
Únete a nosotros para esta masterclass para desbloquear todo el potencial de Postman para las pruebas de API, agilizar tus procesos de prueba y mejorar la calidad y fiabilidad de tu software. Ya seas un principiante o un probador experimentado, esta masterclass te equipará con las habilidades necesarias para sobresalir en las pruebas de API con Postman.
Monitoreo 101 para Desarrolladores de React
React Summit US 2023React Summit US 2023
107 min
Monitoreo 101 para Desarrolladores de React
Top Content
WorkshopFree
Lazar Nikolov
Sarah Guthals
2 authors
Si encontrar errores en tu proyecto frontend es como buscar una aguja en un pajar de código, entonces el monitoreo de errores de Sentry puede ser tu detector de metales. Aprende los conceptos básicos del monitoreo de errores con Sentry. Ya sea que estés ejecutando un proyecto de React, Angular, Vue, o simplemente JavaScript “vainilla”, mira cómo Sentry puede ayudarte a encontrar el quién, qué, cuándo y dónde detrás de los errores en tu proyecto frontend.
Nivel de la masterclass: Intermedio
Testing Web Applications Using Cypress
TestJS Summit - January, 2021TestJS Summit - January, 2021
173 min
Testing Web Applications Using Cypress
Top Content
Workshop
Gleb Bahmutov
Gleb Bahmutov
Esta masterclass te enseñará los conceptos básicos para escribir pruebas end-to-end útiles utilizando Cypress Test Runner.
Cubriremos la escritura de pruebas, cubriendo cada característica de la aplicación, estructurando pruebas, interceptando solicitudes de red y configurando los datos del backend.
Cualquiera que conozca el lenguaje de programación JavaScript y tenga NPM instalado podrá seguir adelante.
Mejores Prácticas para Escribir y Depurar Pruebas de Cypress
TestJS Summit 2023TestJS Summit 2023
148 min
Mejores Prácticas para Escribir y Depurar Pruebas de Cypress
Top Content
Workshop
Filip Hric
Filip Hric
Probablemente conozcas la historia. Has creado un par de pruebas y, como estás utilizando Cypress, lo has hecho bastante rápido. Parece que nada te detiene, pero luego - prueba fallida. No fue la aplicación, no fue un error, la prueba fue... ¿inestable? Bueno sí. El diseño de la prueba es importante sin importar la herramienta que utilices, incluyendo Cypress. La buena noticia es que Cypress tiene un par de herramientas bajo su cinturón que pueden ayudarte. Únete a mí en mi masterclass, donde te guiaré lejos del valle de los anti-patrones hacia los campos de pruebas estables y siempre verdes. Hablaremos sobre los errores comunes al escribir tu prueba, así como depurar y revelar problemas subyacentes. Todo con el objetivo de evitar la inestabilidad y diseñar pruebas estables.