Probando Runtimes Alternativos con Node y VTest

Rate this content
Bookmark

Una inmersión profunda en cómo construimos soporte para ejecutar pruebas de VTest en el runtime de Cloudflare Workers. Comenzaremos dando una visión general de la plataforma de desarrollo de Cloudflare, incluyendo nuestro runtime de JavaScript de código abierto workerd y el simulador local Miniflare. A continuación, hablaremos sobre cómo funciona VTest y proporciona soporte para runtimes personalizados, utilizando Node.js como controlador para ejecutar pruebas en otro entorno. Describiremos los detalles de nuestro pool personalizado de VTest y cómo agregamos soporte para evaluación de código dinámico a nuestro runtime. Por último, hablaremos sobre cómo mejoramos la ergonomía del desarrollador con almacenamiento aislado por prueba, ayudantes de prueba para acceder directamente a las instancias de Durable Object y soporte para simulación declarativa de solicitudes HTTP, y cómo creamos un servicio para construir tipos para las configuraciones de compatibilidad específicas de los usuarios.

Brendan Coll
Brendan Coll
25 min
04 Apr, 2024

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Bienvenidos a mi charla sobre la prueba de runtimes alternativos con Node y VTest. VTest es un popular framework de pruebas que permite la evaluación de código dinámico y se ejecuta dentro de los workers de Cloudflare. Los objetos duraderos proporcionan instancias de clases JavaScript distribuidas con identificadores únicos y almacenamiento persistente para una mejor experiencia de desarrollo. El framework de pruebas en los workers de Cloudflare deshace automáticamente las escrituras en el almacenamiento y admite la generación de datos. También es posible simular solicitudes fetch salientes en los workers de Cloudflare.

Available in English

1. Introducción a Cloudflare Workers y Pruebas

Short description:

Bienvenidos a mi charla sobre la prueba de entornos de ejecución alternativos con Node y VTest. Soy Brendan, un ingeniero de sistemas en Cloudflare. Los workers de Cloudflare son un entorno de ejecución para implementar código de manejo de HTTP. Utilizamos un entorno de ejecución personalizado basado en V8 llamado workerd y una biblioteca de Node llamada Miniflare. Hablemos sobre las pruebas. Tenemos un nuevo sistema que admite tanto pruebas de integración como pruebas unitarias.

Hola a todos. Bienvenidos a mi charla sobre la prueba de entornos de ejecución alternativos con Node y VTest. Esto será una inmersión profunda en cómo construimos la integración de VTest en los workers de Cloudflare, pero las técnicas también serán aplicables a otros entornos de ejecución. Soy Brendan. Creé Miniflare, un simulador completamente local para los workers de Cloudflare. Ahora soy un ingeniero de sistemas en Cloudflare, enfocándome específicamente en las herramientas de desarrollo de los workers. Ya he mencionado los workers de Cloudflare varias veces antes, pero ¿qué son? Escriben un código de manejo de HTTP, lo publican en nuestra plataforma, y luego les proporcionamos una URL para ejecutarlo. Nuestro entorno de ejecución proporciona API estándar similares a las que encontrarían en un navegador web. Implementamos su código en todas las ubicaciones de Cloudflare, por lo que sus usuarios obtienen un acceso de baja latencia sin importar dónde se encuentren. Importante, prácticamente no hay tiempo de inicio en frío. Nuestro entorno de ejecución se basa en aislamientos de V8, no en contenedores o máquinas virtuales. Si les interesa cómo hacemos esto, hay una excelente charla del arquitecto de los workers de Cloudflare, Kenton, llamada Fine Grain Sandboxing with V8 Isolates. Debería ser uno de los primeros resultados si lo buscan en Google. Además de las API web estándar, también proporcionamos API de tiempo de ejecución para acceder al resto de la plataforma de desarrollo de Cloudflare, por ejemplo, el acceso al almacenamiento clave-valor. Aquí, el almacenamiento es un enlace a un espacio de nombres KB de un worker. Podemos obtener, poner, eliminar y listar valores como se esperaría. Y también hay otros tipos de enlaces. Cosas como almacenes de blobs, bases de datos SQLite, y otros workers también. Utilizamos un entorno de ejecución personalizado basado en V8 llamado workerd para ejecutar su código. Luego construimos esta cosa llamada Miniflare, que es una biblioteca de Node que proporciona una API de JavaScript en la parte superior de workerd, y también proporciona simuladores locales para el resto de la plataforma de desarrollo.

Ahora que hemos explicado los conceptos básicos de los workers, hablemos sobre las pruebas. Supongamos que tenemos este worker que suma dos números y nos gustaría escribir pruebas para verificar que su comportamiento sea correcto. Hay un par de formas en las que podríamos hacer esto. Podríamos escribir una prueba de integración que inicie una instancia local de nuestro entorno de ejecución, envíe una solicitud HTTP y verifique la respuesta, o podríamos escribir una prueba de unidad que importe funciones directamente de un worker y verifique sus valores de retorno. Para admitir pruebas de unidad, necesitamos acceder a las API de tiempo de ejecución de los workers dentro del ejecutor de pruebas para que la función se ejecute con el ámbito global correcto. Proporcionamos algunas formas diferentes de hacer esto en la actualidad, pero tienen sus limitaciones. Esta charla explicará cómo construimos un nuevo sistema que admite ambos tipos de pruebas. Antes de continuar, repasemos los puntos clave que acabamos de cubrir. Tenemos un entorno de ejecución personalizado basado en V8 que implementa principalmente API estándar web como los navegadores, por ejemplo, fetch, request, response, web crypto. También implementamos algunas API no estándar, específicamente para casos de uso en el lado del servidor.

2. Descripción general e implementación de VTest

Short description:

Hoy, cubriremos cómo funciona VTest, la evaluación de código dinámico en tiempo de ejecución, la ejecución de VTest en el tiempo de ejecución del worker, la mejora de la experiencia del desarrollador y la simulación declarativa de solicitudes. VTest es un popular marco de pruebas con ejecuciones rápidas y utiliza un grupo de hilos de trabajadores de nodo de forma predeterminada. Para ejecutar pruebas dentro de los workers, ejecutamos el ejecutor de pruebas dentro de workerd y utilizamos WebSockets para la comunicación. VTest proporciona una API para implementar grupos personalizados.

Como conectar a bases de datos, por ejemplo. Sin más introducción, permítanme darles un resumen de lo que voy a hablar hoy. En primer lugar, cubriremos cómo funciona VTest y cómo podemos cambiar dónde se ejecutan las pruebas. Luego veremos cómo agregamos soporte para la evaluación de código dinámico en tiempo de ejecución. A continuación, veremos cómo juntamos esos elementos primitivos para ejecutar VTest en el tiempo de ejecución del worker. Después de eso, veremos las formas en que hemos mejorado la experiencia del desarrollador, comenzando con el almacenamiento de partes aisladas. Luego echaremos un vistazo rápido a las funciones auxiliares para llamar directamente a los métodos de objetos duraderos, y finalmente, nos centraremos en la simulación declarativa de solicitudes. Así que, comencemos con una introducción a VTest. VTest es un marco de pruebas muy popular dentro de la comunidad de JavaScript, que proporciona ejecuciones muy rápidas con recarga de módulos en caliente, instantáneas y simulaciones. Hay un host que ejecuta un nodo y proporciona una CLI, secuencias, pruebas y reportes de salida, y un grupo que genera hilos o procesos para ejecutar las pruebas. Por defecto, VTest utiliza un grupo de hilos de trabajadores de nodo para proporcionar aislamiento y paralelismo en las ejecuciones de pruebas. Pero debido a que el hilo de trabajador se ejecuta en nodo, sus pruebas tienen acceso a los módulos y globales incorporados de nodo y todas esas cosas. Para ejecutar su código y otras dependencias, VTest utiliza un paquete llamado Vite node, y esto transforma su código con Vite y lo ejecuta dinámicamente en un hilo de trabajador. Si queremos ejecutar pruebas dentro de los workers, necesitamos acceso al tiempo de ejecución de los workers definido en nuestro tiempo de ejecución de worker. Sin embargo, hay un pequeño problema aquí, y es que no podemos realmente hacer referencia a clases de JavaScript a través de un límite de proceso. En su lugar, nuestro enfoque es ejecutar el ejecutor de pruebas completo dentro de workerd y utilizar WebSockets para la comunicación entre el host de nodo y el proceso de workerd. ¿Cómo lo hacemos realmente? Afortunadamente, VTest proporciona una API para implementar grupos personalizados, grupos que exportan una función que devuelve un objeto con una función para ejecutar pruebas. La función para ejecutar pruebas acepta una matriz de archivos de proyecto, especifica dos grupos para ejecutar y cualquier archivo que deba ser invalidado porque ha cambiado. Para demostrar cómo se vería esto, vamos a

3. VTest Worker Thread and Test Runner

Short description:

Creamos un canal RPC y usamos un canal de mensajes para la comunicación. Se ensambla y se pasa datos al nuevo hilo de trabajador. En el trabajador, se importa el script de trabajador de VTest y se llama al método run. Se esperan y resuelven las promesas para informar de cualquier error. VTest utiliza un host de nodo para orquestar pruebas e informar resultados, y el código del ejecutor de pruebas está diseñado para ejecutarse en el entorno de un trabajador. VTest también utiliza la evaluación de código dinámico dentro del ejecutor de pruebas.

Creamos un grupo de hilos de trabajadores simplificado. Por cada canal de especificación, creamos un canal RPC y usamos un canal de mensajes para la comunicación aquí, pero podemos cambiar esto por un WebSocket. El método create de la función RPC es proporcionado por VTest y devuelve un objeto con funciones para obtener módulos del servidor de nodo e informar resultados de pruebas. A continuación, ensamblamos los datos para pasar al nuevo hilo de trabajador. Pasamos el archivo de prueba que VTest debe ejecutar en este trabajador y la configuración del proyecto. También pasamos el lado del trabajador del canal de mensajes. Ahora podemos iniciar un trabajador. En realidad, aquí usarías una implementación de grupo de trabajadores, como Pacino o TinyPool. Pero estamos usando trabajadores simples del módulo integrado del hilo de trabajador. Queremos mantener esto simple. En el trabajador, importamos el script de trabajador de VTest y llamamos al método run en él. Podemos iniciar un proceso aquí en lugar de un nuevo trabajador. Y en nuestro caso, en realidad estaremos iniciando un proceso de trabajador aquí. Pero también podrías iniciar cualquier otro tiempo de ejecución aquí o conectarte a una máquina diferente o hacer algo completamente diferente. Uno de los grupos de VTest realiza la comprobación de tipos. En realidad, no es necesario ejecutar los archivos de prueba como JavaScript. Por último, esperemos un mensaje de resultado del trabajador e instalamos estas promesas en el array. Luego podemos esperar a que todas las promesas se resuelvan e informar cualquier error como un error agregado. Y con eso, tenemos un grupo básico de hilos. Podemos usarlo especificando la propiedad de grupo en nuestra configuración de VTest. Ten en cuenta que también podemos pasar opciones al grupo con la propiedad de opciones de grupo. Ejecutar MPXVTest utilizará nuestro grupo y ejecutará nuestras pruebas correctamente. Entonces, repasemos lo que hemos cubierto hasta ahora. Los puntos clave son que VTest utiliza un host de nodo para orquestar pruebas e informar resultados. Los grupos deciden qué hacer con los archivos de prueba. En este ejemplo, hemos ejecutado los archivos de prueba en un hilo de trabajador de nodo. Pero para la integración de los trabajadores, querremos ejecutarlos en procesos de trabajador en su lugar. El código del ejecutor de pruebas que utiliza VTest está diseñado para ejecutarse en nodo, pero lo ejecutaremos en el entorno de un trabajador en su lugar. Genial. Mencioné que VTest utiliza la evaluación de código dinámico dentro del ejecutor de pruebas. Explorémoslo en más detalle.

4. Custom Pool and Dynamic Code Execution

Short description:

Los mensajes entre el grupo y el trabajador incluyen los métodos RPC fetch y resolve ID. Fetch agrupa el código en una ruta especificada utilizando VT para la ejecución dinámica en el trabajador. Resolve ID devuelve la ruta del archivo a un módulo para la importación dinámica. Necesitamos ejecutar código JavaScript desde una cadena e importar módulos desde el disco.

Si volvemos a nuestro grupo personalizado anterior, veamos los mensajes que se envían entre el grupo y el trabajador. Veremos que hay algunos métodos RPC diferentes. Los dos más relevantes para nosotros son fetch, que transforma una ruta con VT en el host. Entonces, básicamente agrupa todo el código en esa ruta utilizando VT. Luego devuelve los resultados para ser ejecutados dinámicamente en el trabajador. Ten en cuenta que estas importaciones se han reemplazado con llamadas especiales a las funciones de VT. Así es como VT implementa los límites de reemplazo de módulos en la simulación de módulos. El otro método relevante es resolve ID, que toma un especificador y un referente, y luego devuelve la ruta del archivo a un módulo. Si está en el directorio de módulos de nodo, VTest intentará importarlo dinámicamente. Con esto en mente, tenemos dos requisitos. Necesitamos poder ejecutar código JavaScript arbitrario desde una cadena y necesitamos poder importar módulos arbitrarios desde

5. Dynamic Code Evaluation and Module Fallback

Short description:

Por razones de seguridad, agregamos una vinculación de evaluación insegura solo local para permitir la evaluación de código dinámico controlado. Esta seguridad basada en capacidades permite la ejecución segura de código que depende de eval. Aunque este enfoque funciona para el código JavaScript, no puede evaluar directamente los módulos ES. Para manejar la carga de módulos, introdujimos un servicio de respaldo de módulos que resuelve las importaciones mediante solicitudes HTTP. Este servicio proporciona un mecanismo de respaldo para las importaciones no resueltas y admite la resolución similar a la de Node con la capacidad de detectar exportaciones con nombre.

disco. Por razones de seguridad, el tiempo de ejecución de los trabajadores deshabilita explícitamente la evaluación dinámica de código en producción, por lo que necesitamos encontrar una forma de hacer esto manteniendo estas garantías de seguridad. Para resolver este problema, agregamos un nuevo tipo de vinculación de evaluación insegura solo local. Esto te permite llamar a eval indirecto o al constructor de funciones nuevo o algunas otras cosas también. Al agregar esto como una vinculación, podemos controlar a qué código tiene acceso eval. Esto es muy importante para las pruebas, ya que no queremos que el código que depende de eval pase las pruebas localmente pero falle cuando se implemente. Podemos ver en este ejemplo que pasamos la vinculación de evaluación insegura a la función evaluar, pero no a la función doble. Entonces, solo evaluar puede llamar a eval. Esta es una forma básica de seguridad basada en capacidades si estás familiarizado con eso. Esto funciona muy bien para el código de JavaScript, pero desafortunadamente, no puedes evaluar los módulos ES, por lo que no pudimos usar esto para implementar la carga de módulos desde el disco, a menos que construyéramos nuestro propio cargador de módulos en JavaScript, pero reutilizaríamos la lógica de WorkerD para esto. Por lo general, WorkerD requiere que todos los módulos se especifiquen de antemano, lo cual tiene sentido si estás operando una plataforma de funciones como servicio, donde subirás código a la plataforma. Cuando un módulo importa otro módulo, resolvemos el especificador relativo a la URL de referencia y buscamos eso en el registro. En este caso, el especificador es math add, y el referente es barra diagonal índice. Encontramos el módulo en el registro, nos aseguramos de que esté inicializado y lo devolvemos. Sin embargo, si agregamos una importación a un módulo que no existe, esto fallará en tiempo de ejecución. Para el VTestWorker, no sabemos qué módulos importaremos hasta que comencemos a ejecutar pruebas. Necesitamos alguna forma de definir un respaldo si el módulo no se encuentra en el registro. Y ahí es exactamente donde entra en juego el servicio de respaldo de módulos. Esto es algo nuevo que agregamos que, si está habilitado, las importaciones no resueltas se convierten en solicitudes HTTP, incluyendo el especificador y el referente. También incluimos si esto fue una importación o un require, ya que tienen diferentes semánticas. El servicio puede responder con una definición de módulo o una redirección a un especificador diferente si la ubicación resuelta es diferente al destino. Requiere una sincronización, por lo que esto bloqueará el hilo principal hasta que el servicio responda. Esto es algo así como cómo funcionan los módulos en el navegador. Nuestra implementación, en cambio, implementa una resolución similar a la de Node con soporte para detectar automáticamente exportaciones con nombre en los módulos de CommonJS, como Node. Y con eso, tenemos todo lo que necesitamos para la evaluación de código dinámico. Podemos ejecutar código arbitrario con vinculaciones de eval inseguras y podemos importar módulos arbitrarios con el servicio de respaldo de módulos. Estas características nos permiten muchos otros casos de uso. Estamos construyendo efectivamente un tiempo de ejecución personalizado de VT aquí, que podría usarse en el futuro para servidores de desarrollo de meta framework, lo que te permitirá tener recarga de módulos en caliente para tu código de servidor mientras aún tienes acceso a todas las vinculaciones de CloudFlare. Ahora que podemos ejecutar e importar código arbitrario, el siguiente paso es obtener el ejecutor de pruebas de VTest. Este trabajador realiza algunos trabajos en segundo plano, luego registra en la consola.

6. Request Context and Durable Objects

Short description:

Cada solicitud entrante en Workers tiene su propio contexto de solicitud, que se elimina cuando se devuelve una respuesta. Para solucionar esto, necesitamos extender la vida útil del contexto de solicitud para el trabajo en segundo plano. Afortunadamente, los objetos duraderos proporcionan instancias de clase JavaScript distribuidas con identificadores únicos y almacenamiento persistente. Estas instancias se pueden utilizar para almacenamiento volátil en memoria y son similares a los actores. Los objetos duraderos permiten la construcción de aplicaciones colaborativas con instancias ubicadas más cerca de cada usuario. El objetivo futuro es permitir que los objetos duraderos se muevan entre centros de datos.

Excepto que, si lo ejecutas, no lo hace. Si le envías una solicitud, nunca verás el registro de la consola. Esto se debe a que cada solicitud entrante en Workers tiene su propio contexto de solicitud. Las operaciones de E/S asíncronas, como las solicitudes de búsqueda o los tiempos de espera, deben realizarse dentro de un contexto de solicitud. Y cuando se devuelve una respuesta, el contexto de solicitud se elimina y todas las operaciones asincrónicas pendientes se cancelan. En este caso, el tiempo de espera se borra automáticamente. Esta limitación nos permite mejorar el rendimiento general de Workers. Para solucionar esto, necesitamos extender la vida útil del contexto de solicitud hasta que se complete el trabajo en segundo plano. Esto es bastante problemático para las pruebas, que tienen muchas operaciones asincrónicas. No queremos tener que esperar hasta, como, no queremos tener que agregar esta espera hasta que a todas ellas. Afortunadamente, también tenemos estas cosas llamadas objetos duraderos. Los objetos duraderos son esencialmente instancias de clase JavaScript distribuidas en todo el mundo. Cada instancia tiene un identificador único y su propio almacenamiento persistente. Las propiedades de la instancia se pueden utilizar como almacenamiento volátil en memoria. Si estás familiarizado con los actores, es algo parecido a eso. Como ejemplo, podrías definir una clase de objeto duradero para un usuario en tu aplicación y cada usuario tendría su propia instancia del objeto ubicada más cerca de ellos. Veamos un ejemplo. Digamos que estamos construyendo un editor de documentos colaborativo. Definiremos una clase de objeto duradero para un documento. Esta es una clase JavaScript normal con un método de búsqueda especial para manejar las solicitudes. Si uso la nueva función de identificador único, y como sé que este identificador es único, sé que no existe otro objeto en el mundo con ese identificador. Entonces construyo una instancia de la clase en el centro de datos más cercano a mí.

Ahora digamos que mi colega en Estados Unidos quiere crear un documento. En lugar de usar un nuevo identificador único, llaman a la función de identificador a partir del nombre. Como no sabemos si ya existe un objeto con ese identificador, el sistema primero debe hacer una búsqueda global. Ahora que estamos seguros de que el objeto aún no existe, podemos crear una nueva instancia nuevamente en el centro de datos más cercano a mi colega. Y finalmente, digamos que tengo otro colega en Australia. Ellos quieren acceder a mi documento, así que les comparto el identificador. Utilizan el método de cadena de identificador para obtener un identificador de objeto duradero y se conectan a mi instancia existente. Debido a que están al otro lado del mundo, su latencia es bastante alta. Aún no hemos implementado esto, pero en el futuro, estamos

7. Integration Tests and Durable Object Context

Short description:

Los objetos duraderos reutilizan el mismo contexto de solicitud, lo que permite la ejecución de pruebas sin preocuparse por esperas y tiempos de espera. Las pruebas de integración para Cloudflare utilizan un módulo de prueba que devuelve el entorno actual. Al importar los controladores de los workers y llamarlos directamente, el comportamiento de las pruebas coincide con el de producción. Los usuarios pueden configurar un punto de entrada principal para la recarga en caliente de módulos, lo que garantiza que los módulos se invaliden y las pruebas se vuelvan a ejecutar con un nuevo código.

Con la esperanza de permitir que los objetos duraderos se muevan. Esto se vería algo así, en este caso. Podría moverse a India para estar más cerca de mi colega. Veamos cómo podría ser el code para un objeto duradero. Encajar un editor colaborativo en una diapositiva es complicado, así que nos quedaremos con un contador de solicitudes simple. Cada vez que llega una solicitud, hasheamos la URL en un ID de objeto duradero y obtenemos un stub de ese objeto y reenviamos las solicitudes a él. La instancia del contador incrementará y devolverá su nuevo valor. Lo importante para nosotros es que los objetos duraderos reutilizan el mismo contexto de solicitud para todas las solicitudes y extienden automáticamente su tiempo de vida. Al ejecutar la ejecución de pruebas dentro de un solo objeto duradero, no necesitamos preocuparnos por llamar a waitUntil. Esto es excelente para ejecutar solicitudes como conexiones WebSocket. Lo que queremos es un objeto duradero que termine una conexión WebSocket, importe el script del worker VTest y use mensajes WebSocket para RPC.

Este es un objeto duradero que hace eso. Comenzaremos creando un par de WebSockets, que es una API de workers no estándar, algo así como MessageChannel, pero para WebSockets. Te quedas con una mitad y devuelves la otra mitad en la respuesta. Luego extraemos los datos para este worker de una cabecera utilizando una versión más avanzada de JSON.parse que admite tipos estructurados con referencias circulares. Utilizamos una clase de puerto de mensajes WebSocket personalizada para adaptar un WebSocket con una interfaz de puerto de mensajes. Nuevamente, con soporte para tipos serializables estructurados. Todavía estamos tratando de ejecutar código diseñado para Node aquí, pero afortunadamente tenemos esta bandera de compatibilidad con Node.js que habilita el soporte para un subconjunto de los módulos integrados de Node y luego, al rellenar algunos módulos integrados más con el servicio de módulos, podemos hacer que VTest se ejecute en WorkerD. Esto nos permite ejecutar pruebas que importan funciones básicas, las llaman y verifican sus valores de retorno, lo cual es un buen comienzo, pero ¿qué pasa con esos parámetros de entorno y contexto que mencioné antes? ¿Cómo escribimos pruebas que dependan de ellos? Para esto, definiremos un módulo de prueba de Cloudflare que se devuelve mediante el servicio de fallback de módulos. Usamos una variable de nivel de módulo para almacenar el entorno actual y exportamos una función para establecerlo. Nuestro módulo de prueba de Cloudflare reexporta un subconjunto de un módulo interno para que los usuarios no puedan manipular cosas ocultas. La variable de entorno se establece utilizando el segundo parámetro del constructor de nuestros objetos de ejecución y con eso, tenemos pruebas de integración. Podemos importar controladores de workers y llamarlos directamente. ¿Recuerdas lo que dije sobre el contexto de solicitud antes? El ejecutor de pruebas se está ejecutando dentro de un contexto de objeto duradero, por lo que no tenemos que preocuparnos por esperas y tiempos de espera. Debido a que estamos llamando a los controladores de workers dentro de ese contexto, ellos tampoco tienen que preocuparse por esperas y tiempos de espera, lo cual no es realmente lo que queremos de una prueba de integración. Nos gustaría que el comportamiento coincida con el de producción. En cambio, permitimos a los usuarios configurar un punto de entrada principal. En el worker que implementa el objeto ejecutor, definimos un controlador que importa el punto de entrada con VT y reenvía la llamada al controlador. Debido a que estamos importando con VT, obtenemos la recarga en caliente de módulos de forma gratuita. Cuando el punto de entrada principal o una de sus dependencias cambia, los módulos se invalidan y las pruebas se vuelven a ejecutar con un nuevo código. Luego definimos una vinculación de worker al worker actual en el

8. Durable Objects and Developer Experience

Short description:

El uso de esto nos proporciona una API más ergonómica para las pruebas de integración. Los objetos duraderos son potentes y proporcionan todo lo necesario para escribir pruebas unitarias y de integración para los workers. Las secciones siguientes cubrirán funcionalidades adicionales para mejorar la experiencia del desarrollador.

El módulo de prueba llamado self. El uso de esto nos proporciona una API más ergonómica para las pruebas de integración. No es necesario preocuparse por pasar EMV o CTX. Lo interesante de esto es que el worker sigue ejecutándose en el mismo ámbito global que las pruebas. Si importáramos el módulo principal en este archivo, sería exactamente la misma instancia que utiliza el controlador envuelto. En resumen, los objetos duraderos son increíblemente potentes. Apenas hemos rascado la superficie de lo que es posible aquí. Definimos un módulo de prueba de Cloudflare con funciones auxiliares para acceder a las vinculaciones, crear contextos de ejecución y realizar pruebas de integración con self. Así que básicamente tenemos todo lo que necesitamos para escribir pruebas unitarias y de integración para los workers ahora. Las próximas secciones tratan sobre cómo agregamos funcionalidades adicionales para mejorar la

9. Isolated Per Test Storage and Seeding Data

Short description:

Las pruebas deben ser autocontenidas y ejecutables en cualquier orden. Las escrituras en el almacenamiento deben deshacerse al final de cada prueba. Puede ser complicado realizar un seguimiento manual de todas las escrituras y deshacerlas. Con el marco de pruebas, las escrituras en el almacenamiento se deshacen automáticamente. Se admite la generación de datos utilizando una pila. Cada prueba obtiene su propio entorno de almacenamiento que se deshace automáticamente para la siguiente prueba.

experiencia del desarrollador. Comencemos con el almacenamiento aislado por prueba. La mayoría de las aplicaciones de workers tendrán al menos una vinculación a un servicio de almacenamiento de Cloudflare. Idealmente, las pruebas deben ser autocontenidas y ejecutables en cualquier orden o por separado. Para hacer esto posible, las escrituras en el almacenamiento deben deshacerse al final de cada prueba, para que las lecturas de otras pruebas no se vean afectadas. Si bien es posible hacer esto manualmente, puede ser complicado realizar un seguimiento de todas las escrituras y deshacerlas en el orden correcto. Tomemos las siguientes dos funciones que obtienen y agregan elementos a la lista proporcionada. Idealmente, escribiríamos pruebas como esta, utilizando la misma clave en ambas pruebas. Tenga en cuenta que la adición de dos a la lista A se ha deshecho antes de la segunda prueba. Cuando obtenemos la lista A en la segunda prueba, no vemos dos elementos allí. Podemos implementar esto con un poco de código adicional antes de nuestras pruebas que almacena el valor de cada lista antes de la prueba y luego lo restaura después. Sin embargo, esto es mucho trabajo. Es un poco más fácil con el gancho de finalización de prueba recientemente introducido, pero aún así debemos recordar qué claves se escribieron o enumerarlas al comienzo y al final de las pruebas. También tendríamos que gestionar esto para KVE, r2, cachés y cualquier otro servicio de almacenamiento que utilicemos. Todo esto es propenso a errores. Idealmente, el marco de pruebas debería encargarse de esto por nosotros. Cualquier escritura en el almacenamiento realizada en una prueba se deshace automáticamente al final de la prueba. Para admitir la generación de datos incluyendo los bloques describe anidados, utilizamos una pila. Cada vez que ingresamos a una prueba o bloque describe, agregamos un nuevo marco a la pila. Todas las operaciones se escriben en el marco superior. Para demostrar esto, simplifiquemos los ayudantes anteriores para que siempre lean y escriban en la misma lista. Comenzamos con un solo marco raíz de la pila. Todas las reglas de antes de nivel superior se escriben en este marco. Cuando comenzamos una prueba, agregamos un nuevo marco a la pila. Esto significa que cada prueba obtiene su propio entorno de almacenamiento copiado del padre. Todas las operaciones de escritura se realizan en el marco más alto En este caso, el beforeEach escribe en el marco de la prueba. Al igual que cualquier operación en la propia prueba. Cuando una prueba finaliza, su marco se elimina y creamos un nuevo marco para la próxima prueba. Esto significa que todos los cambios realizados en esa prueba se deshacen automáticamente para la próxima prueba. La prueba B escribirá en su marco y luego se eliminará cuando la prueba finalice.

10. Testing Describe Blocks and Durable Objects

Short description:

Para los bloques describe, se aplica el mismo proceso. Implementamos almacenamiento aislado utilizando una pila de archivos SQLite en disco. Para activar el empuje y el desapilamiento, utilizamos un ejecutor de pruebas personalizado V. Envolvemos las clases de objetos duraderos de manera similar a los controladores regulares y agregamos un controlador de solicitudes especial para ejecutar funciones arbitrarias en el contexto de los objetos duraderos.

Para los bloques describe, se aplica el mismo proceso. Cuando ingresamos al bloque describe, empujamos un nuevo marco a la pila. Todas las reglas antes en el bloque describe escribirán en este marco y también hay que tener en cuenta que todas las reglas antes se ejecutan antes de cada uno. Cuando comenzamos una nueva prueba, empujamos un nuevo marco a la pila, luego ejecutamos las reglas antes del nivel superior, luego las reglas antes del nivel descrito y luego la prueba en sí. Hay que tener en cuenta que todas estas operaciones escriben en el marco de la prueba. Por lo tanto, cuando la prueba se completa y se desapila el marco, todas las escrituras se deshacen. La siguiente prueba hará exactamente lo mismo. Y luego, cuando esa prueba termine, desapilaremos el marco superior. Luego, cuando el bloque describe termine, desapilaremos el siguiente marco hasta que nos quede el marco raíz nuevamente. Miniflare implementa simuladores para servicios de almacenamiento sobre objetos duraderos con un almacén de blobs separado. Para implementar un almacenamiento aislado, implementamos una pila de archivos SQLite en disco. Los almacenes de blobs se implementan como un almacén separado y se conservan a través de las operaciones de pila. Estos se limpian al finalizar las ejecuciones de las pruebas. Si bien esto funciona, implica copiar muchos archivos SQLite. Nos gustaría explorar el uso de puntos de guardado de SQLite para una solución más eficiente. Para activar el empuje y el desapilamiento, utilizamos un ejecutor de pruebas personalizado V, que le permite conectarse a diferentes ganchos del ciclo de vida de las pruebas de V. Empujamos la pila antes de ejecutar un bloque descrito o comenzar un intento de prueba y desapilamos la pila después de finalizar un intento de prueba o bloque descrito. Mencioné los objetos duraderos varias veces ahora. Pensemos en cómo los probaríamos realmente. Queremos poder unit test objetos duraderos como clases regulares de JavaScript. Esto significa llamar y espiar métodos y acceder a propiedades. También sería útil tener acceso directo al almacenamiento para generar data y verificar los efectos secundarios. Desafortunadamente, no podemos simplemente construir instancias de la clase. Esto rompería las garantías de unicidad de los objetos duraderos. Los objetos duraderos también tienen un comportamiento de bloqueo implícito bastante complicado, que debería reproducirse llamando a métodos. Debes estar en su contexto de solicitud. Para resolver todos estos problemas, envolvemos las clases de objetos duraderos de manera similar a los controladores regulares como lo hicimos para las pruebas de integración con self. Luego agregamos un controlador de solicitudes especial para ejecutar funciones arbitrarias en el contexto de los objetos duraderos. Veamos cómo se ve esto. En el módulo de prueba de Cloudflare, definimos una función run in durable object que acepta un objeto duradero.

11. Manejo de solicitudes de objetos duraderos

Short description:

Esta función espera los argumentos de la instancia y el estado persistente. Almacenamos la función en un mapa de nivel de módulo y enviamos una solicitud al objeto duradero con el ID que lo almacenamos. En el controlador de solicitudes de objetos duraderos, verificamos si se estableció el ID.

stub y una función para ejecutar. Esta función espera los argumentos de la instancia y el estado persistente. Almacenamos la función en un mapa de nivel de módulo y enviamos una solicitud al objeto duradero con el ID que lo almacenamos. En el controlador de solicitudes de objetos duraderos, verificamos si se estableció el ID. Si no se estableció, reenviamos la solicitud. Si se estableció, extraemos la función del mapa de nivel de módulo y la ejecutamos en el contexto del objeto duradero. Ten en cuenta que estamos utilizando el mismo mapa que antes y confiando en que el objeto duradero del usuario se ejecute en el mismo islet que el ejecutor de pruebas. Almacenamos el resultado de la función en el mapa y luego, en la función principal, leemos y devolvemos esto de nuevo al

12. Manejo de solicitudes de búsqueda salientes

Short description:

Esto aborda todos nuestros requisitos anteriores. Ahora podemos llamar métodos y propiedades en las instancias directamente. Tenemos acceso directo al almacenamiento para sembrar datos. Importante, la función de devolución de llamada se ejecuta en el contexto de la solicitud del objeto duradero. Por último, cubramos rápidamente cómo manejamos la simulación de solicitudes de búsqueda salientes. La mayoría de los trabajadores realizarán solicitudes de búsqueda salientes. Es útil simular respuestas a estas solicitudes para no tener que probar contra producción o configurar servidores de prueba adicionales.

usuario. Esto aborda todos nuestros requisitos anteriores. Ahora podemos llamar métodos y propiedades en las instancias directamente. Tenemos acceso directo al almacenamiento para sembrar data. Importante, la función de devolución de llamada se ejecuta en el contexto de la solicitud del objeto duradero.

Por último, cubramos rápidamente cómo manejamos la simulación de solicitudes de búsqueda salientes. La mayoría de los trabajadores realizarán solicitudes de búsqueda salientes. Es útil simular respuestas a estas solicitudes para no tener que probar contra producción o configurar servidores de prueba adicionales. En MiniFlare, te permitimos especificar un agente simulado de Indici para enrutar. Indici es el paquete que alimenta la implementación de búsqueda integrada en los nodos. La clase de agente simulado proporciona una interfaz declarativa para especificar solicitudes a simular y las respuestas correspondientes a devolver. Esta API es relativamente simple, pero lo suficientemente flexible para casos de uso avanzados. Para implementar esto en nuestra integración de V test, hemos incluido una versión simplificada de Indici que solo contiene el agente simulado code. En nuestro paquete especial, exponemos ganchos para establecer el despachador global. Luego, parcheamos en tiempo de ejecución la función de búsqueda global para pasar a través del agente simulado si está habilitado. Veamos algunos ejemplos de cómo funciona esto. Cuando el agente simulado está deshabilitado, lo evitamos por completo y reenviamos las solicitudes a la función de búsqueda regular. Si el agente simulado está habilitado y la solicitud coincide con uno de sus interceptores, devolverá una respuesta. Si la solicitud no coincide con un interceptor, se pasará a la función de búsqueda original. A menos que llamemos a la función de deshabilitar met connect en el agente simulado, lo que evita las llamadas de red si no se simulan las solicitudes. En este caso, el usuario verá un error. Como mencioné, implementamos esto con una versión personalizada de Indici. Usamos un mapa débil para almacenar la solicitud original para la función de búsqueda original si la solicitud no está simulada. De manera similar, usamos otro mapa débil para almacenar una respuesta de la función de búsqueda original que podemos devolver más tarde. Luego, parcheamos en tiempo de ejecución la función de búsqueda global. Verificamos si el agente está realmente habilitado y pasamos a la función de búsqueda original si no lo está. Luego, convertimos el objeto de solicitud estándar en un formato compatible con Indici y almacenamos la solicitud original en el mapa débil con clave en las opciones de despacho de Indici. Luego, definimos controladores de despacho de Indici que registran cualquier respuesta simulada que recibamos. Estas funciones no se llamarán si la solicitud no coincide con el agente. Luego, definimos controladores de despacho de Indici que registran cualquier respuesta simulada que recibamos.

13. Manejo de solicitudes de búsqueda salientes - Conclusión

Short description:

Estas funciones no se llamarán si la solicitud no coincide con el agente. Definimos el controlador de finalización para la respuesta simulada completa o la respuesta de la función fetch original. Cubrimos cómo funciona VTest, personalizando su comportamiento, evaluación de código dinámico, ejecutando VTest dentro del tiempo de ejecución del worker, almacenamiento aislado, llamando a objetos duraderos directamente y simulación declarativa de solicitudes con Indici. Prueba Cloudflare Workers y encuentra una descripción general y el código en el blog de Cloudflare y el repositorio de GitHub.

Estas funciones no se llamarán si la solicitud no coincide con el agente y llama a la función fetch original. Luego, definimos el controlador de finalización. Esto se llamará cuando se devuelva la respuesta simulada completa o cuando se devuelva una respuesta de la función fetch original. Si se llamó a la función original, podemos obtener la respuesta del mapa débil, nuevamente, utilizando las opciones de despacho como clave. De lo contrario, construimos un objeto de respuesta estándar a partir de las respuestas simuladas. Finalmente, despachamos la solicitud a través del agente simulado y devolvemos la promesa de respuesta. Y con eso, hemos terminado. Hemos cubierto cómo funciona VTest y cómo podemos personalizar su comportamiento con grupos personalizados, cómo agregamos soporte para evaluación de code dinámico en nuestro tiempo de ejecución, utilizando esos elementos primitivos para ejecutar VTest dentro del tiempo de ejecución del worker, cómo mejoramos la experiencia del desarrollador con almacenamiento aislado, llamando a objetos duraderos directamente como clases de JavaScript, y finalmente, simulación declarativa de solicitudes con Indici. Te animo a que pruebes Cloudflare Workers si aún no lo has hecho. Puedes encontrar una descripción general de esta charla en el blog de Cloudflare y todo el code para la integración está en el

QnA

Introducción y Experiencia con Cloudflare Workers

Short description:

Gracias a todos por escuchar. La mayoría de las personas no han utilizado Cloudflare Workers antes, pero definitivamente deberían probarlo. Brandon habla sobre su experiencia con Cloudflare Workers y por qué lo eligió. También menciona la simplicidad y los productos de base de datos integrados. Un miembro de la audiencia pregunta sobre el uso de puntos de guardado de SQLite para implementar almacenamiento aislado, y Brandon explica cómo funciona.

Repositorio de GitHub de Cloudflare Workers SDK. Gracias a todos por escuchar. Estoy muy feliz de tenerlos aquí con nosotros, Brandon, hoy. Y primero que nada, echemos un vistazo a la pregunta de la encuesta. Así que tengo que recordarlo un poco. Preguntaste, ¿has utilizado Cloudflare Workers antes? Y veamos aquí los resultados. Y esto es interesante. La abrumadora mayoría, un 73 por ciento, dice que no. ¿Te sorprende eso, Brandon? Sí, estoy un poco sorprendido, pero también no. Supongo que en el gran esquema de todas estas plataformas, es relativamente nuevo. Pero creo que las personas definitivamente deberían probarlo. Hay muchas cosas geniales que puedes hacer con él. Muchas cosas que lanzamos recientemente para desarrolladores esta semana para Cloudflare. Así que tenemos muchos anuncios nuevos, cosas que las personas definitivamente deberían probar. Hablamos un poco en el backstage, ¿verdad? Y mencionaste que simplemente te encontraste con Cloudflare Workers hace mucho tiempo, hace unos años, donde simplemente lo probaste, no te gustó realmente la experiencia, y así que creaste MiniFlare como resultado, como una respuesta. Quiero decir, en ese momento, ¿por qué elegiste Cloudflare Workers en lugar de, digamos, AWS Lambda o Azure Cloud Functions o cualquier otra cosa? Sí, creo que en ese momento realmente creía en la plataforma. Era simplemente, ignorando la experiencia del desarrollador, era tan simple comenzar. Simplemente escribir código, subirlo a Cloudflare, obtener un punto final HTTP al que puedes acceder. Y también tenía todos estos productos de base de datos integrados, lo que significaba que no tenías que pensar en mucho cuando estás escribiendo tu código, lo cual es fantástico. Tenían esta herramienta, Wrangler Dev, que funcionaba para el desarrollo, pero lo que realmente quería era algo que se ejecutara completamente localmente. Y eso es por qué hice MiniFlare. Sí, interesante. Siento que Cloudflare podría hacer un mejor trabajo realmente anunciando al mundo lo fácil que es trabajar con ellos. Pasemos a las preguntas y veamos qué han enviado los miembros de la audiencia en términos de preguntas. La primera pregunta que veo aquí es que mencionaste el uso de puntos de guardado de SQLite para implementar almacenamiento aislado. ¿Cómo funcionaría eso? Sí, en este momento, como mencioné en la charla, implementamos almacenamiento aislado con esta pila de bases de datos SQLite en disco. SQLite tiene esta función de puntos de guardado incorporada, que te permite implementar transacciones anidadas. Básicamente, puedes crear un punto de guardado y luego volver a ese punto en la base de datos en un momento posterior. Entonces, para el almacenamiento aislado, lo que hacemos es crear un punto de guardado cada vez que lo agregamos a la pila, y luego cuando retrocedemos, básicamente, bueno, retrocedemos cada vez que lo sacamos de la pila. Y esto significa que no tendríamos que copiar ningún archivo de SQLite ni realizar ninguna operación de pila en disco y cosas así. Todo sería manejado por SQLite, que supongo que estaría en disco, pero debería ser mucho más rápido

SQLite, Pruebas Paralelas, Helpers y Keynote

Short description:

Hay charlas en línea increíbles del creador de SQLite, una tecnología muy valorada utilizada en computadoras de aviación en todo el mundo. El orador también aborda las pruebas paralelas en VTest, la disponibilidad de helpers en el módulo de pruebas de Cloudflare y el uso de Keynote para crear presentaciones atractivas.

y más eficiente. Genial, muchas gracias. Y para aquellos que siempre han descuidado mirar SQLite, por cierto, hay charlas increíbles en línea del creador de SQLite. Digamos un producto con una cobertura de pruebas tan alta que actualmente se ejecuta en computadoras y cabinas de aviación en todo el mundo, lo cual es simplemente asombroso. Así que, realmente, una pieza de tecnología increíble. Échale un vistazo a SQLite. La siguiente pregunta es, ¿tienen planes de admitir la ejecución de pruebas VTest completamente paralelas con la sintaxis .concurrent? Sí. Actualmente admitimos cierta concurrency. Si tienes un espacio de trabajo VTest con muchos proyectos diferentes, todos esos proyectos se ejecutarán en paralelo. Si tienes un solo proyecto y habilitas la opción de múltiples workers, cada archivo de prueba se ejecutará en su propio worker, y estos se ejecutarán en paralelo también. La única limitación es que si tienes habilitado el almacenamiento aislado, no podemos ejecutar varios archivos de prueba en el mismo proceso, debido a cómo funciona el almacenamiento aislado y cómo se comparte el almacenamiento entre todos los workers en ejecución. Muy bien, entendido. La siguiente pregunta es, ¿proporcionan otros helpers en el módulo de pruebas de Cloudflare? Sí, como mencioné en la charla, admitimos tanto pruebas unitarias como de integración con esta integración. Proporcionamos un montón de helpers para crear instancias de clases especiales que necesitas pasar a los controladores de workers para las pruebas unitarias. Cosas como el controlador programado para eventos prom, y una coincidencia de mensajes si tienes un evento de cola. También proporcionamos helpers para listar los objetos duraderos en un espacio de nombres de objetos duraderos y forzar la ejecución de estas cosas llamadas alarmas de objetos duraderos, que son como timeouts persistentes. Así que estableces un timeout y, si el objeto duradero se duerme, se asegurará de que el objeto duradero se despierte cuando ese timeout haya transcurrido. También proporcionamos algunos helpers para aplicar migraciones a bases de datos D1. Eso es como nuestra versión alojada de SQLite en la Cloud. Y te permitimos escribir pruebas contra esas bases de datos y aplicar tus migraciones. Genial, suena como una lista realmente completa de módulos y helpers para permitir a los desarrolladores escribir pruebas de alta calidad. Por último, pero no menos importante, la gente se pregunta cómo creas estas animaciones geniales en tu presentación. ¿Qué usaste para crear tu presentación, en realidad? Sí, esta es una presentación de Keynote. Viene incluida, creo, en las versiones de Mac OS de Bournemouth. Y las animations son como transiciones de movimiento mágico. Básicamente, creas dos diapositivas y luego dices que quieres un movimiento mágico, y automáticamente se encargará de la transición entre ellas. Para algunas cosas de texto tienes que ser un poco ingenioso. Y tienes que copiar versiones invisibles del texto arriba y abajo de las diapositivas. Pero eso es probablemente cómo lo hacemos. Muchas gracias. Me encanta cómo aprendimos no solo sobre la tecnología profunda que sucede en CloudFair, sino también un pequeño tutorial aquí sobre cómo usar Keynote de una manera que llame la atención de las personas en una conferencia. Brendan, muchas gracias por esta increíble charla y por unirte a nosotros hoy. Realmente un placer conocerte. Y ahora vamos a Sharon.

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

Network Requests with Cypress
TestJS Summit 2021TestJS Summit 2021
33 min
Network Requests with Cypress
Top Content
Whether you're testing your UI or API, Cypress gives you all the tools needed to work with and manage network requests. This intermediate-level task demonstrates how to use the cy.request and cy.intercept commands to execute, spy on, and stub network requests while testing your application in the browser. Learn how the commands work as well as use cases for each, including best practices for testing and mocking your network requests.
Testing Pyramid Makes Little Sense, What We Can Use Instead
TestJS Summit 2021TestJS Summit 2021
38 min
Testing Pyramid Makes Little Sense, What We Can Use Instead
Top Content
Featured Video
Gleb Bahmutov
Roman Sandler
2 authors
The testing pyramid - the canonical shape of tests that defined what types of tests we need to write to make sure the app works - is ... obsolete. In this presentation, Roman Sandler and Gleb Bahmutov argue what the testing shape works better for today's web applications.
Full-Circle Testing With Cypress
TestJS Summit 2022TestJS Summit 2022
27 min
Full-Circle Testing With Cypress
Top Content
Cypress has taken the world by storm by brining an easy to use tool for end to end testing. It’s capabilities have proven to be be useful for creating stable tests for frontend applications. But end to end testing is just a small part of testing efforts. What about your API? What about your components? Well, in my talk I would like to show you how we can start with end-to-end tests, go deeper with component testing and then move up to testing our API, circ
Test Effective Development
TestJS Summit 2021TestJS Summit 2021
31 min
Test Effective Development
Top Content
Developers want to sleep tight knowing they didn't break production. Companies want to be efficient in order to meet their customer needs faster and to gain competitive advantage sooner. We ALL want to be cost effective... or shall I say... TEST EFFECTIVE!But how do we do that?Are the "unit" and "integration" terminology serves us right?Or is it time for a change? When should we use either strategy to maximize our "test effectiveness"?In this talk I'll show you a brand new way to think about cost effective testing with new strategies and new testing terms!It’s time to go DEEPER!
Playwright Test Runner
TestJS Summit 2021TestJS Summit 2021
25 min
Playwright Test Runner
Top Content
How Bun Makes Building React Apps Simpler & Faster
React Day Berlin 2022React Day Berlin 2022
9 min
How Bun Makes Building React Apps Simpler & Faster
Bun’s builtin JSX transpiler, hot reloads on the server, JSX prop punning, macro api, automatic package installs, console.log JSX support, 4x faster serverside rendering and more make Bun the best runtime for building React apps

Workshops on related topic

Designing Effective Tests With React Testing Library
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Top Content
Featured Workshop
Josh Justice
Josh Justice
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn
How to Start With Cypress
TestJS Summit 2022TestJS Summit 2022
146 min
How to Start With Cypress
Featured WorkshopFree
Filip Hric
Filip Hric
The web has evolved. Finally, testing has also. Cypress is a modern testing tool that answers the testing needs of modern web applications. It has been gaining a lot of traction in the last couple of years, gaining worldwide popularity. If you have been waiting to learn Cypress, wait no more! Filip Hric will guide you through the first steps on how to start using Cypress and set up a project on your own. The good news is, learning Cypress is incredibly easy. You'll write your first test in no time, and then you'll discover how to write a full end-to-end test for a modern web application. You'll learn the core concepts like retry-ability. Discover how to work and interact with your application and learn how to combine API and UI tests. Throughout this whole workshop, we will write code and do practical exercises. You will leave with a hands-on experience that you can translate to your own project.
Detox 101: How to write stable end-to-end tests for your React Native application
React Summit 2022React Summit 2022
117 min
Detox 101: How to write stable end-to-end tests for your React Native application
Top Content
WorkshopFree
Yevheniia Hlovatska
Yevheniia Hlovatska
Compared to unit testing, end-to-end testing aims to interact with your application just like a real user. And as we all know it can be pretty challenging. Especially when we talk about Mobile applications.
Tests rely on many conditions and are considered to be slow and flaky. On the other hand - end-to-end tests can give the greatest confidence that your app is working. And if done right - can become an amazing tool for boosting developer velocity.
Detox is a gray-box end-to-end testing framework for mobile apps. Developed by Wix to solve the problem of slowness and flakiness and used by React Native itself as its E2E testing tool.
Join me on this workshop to learn how to make your mobile end-to-end tests with Detox rock.
Prerequisites- iOS/Android: MacOS Catalina or newer- Android only: Linux- Install before the workshop
API Testing with Postman Workshop
TestJS Summit 2023TestJS Summit 2023
48 min
API Testing with Postman Workshop
Top Content
WorkshopFree
Pooja Mistry
Pooja Mistry
In the ever-evolving landscape of software development, ensuring the reliability and functionality of APIs has become paramount. "API Testing with Postman" is a comprehensive workshop designed to equip participants with the knowledge and skills needed to excel in API testing using Postman, a powerful tool widely adopted by professionals in the field. This workshop delves into the fundamentals of API testing, progresses to advanced testing techniques, and explores automation, performance testing, and multi-protocol support, providing attendees with a holistic understanding of API testing with Postman.
1. Welcome to Postman- Explaining the Postman User Interface (UI)2. Workspace and Collections Collaboration- Understanding Workspaces and their role in collaboration- Exploring the concept of Collections for organizing and executing API requests3. Introduction to API Testing- Covering the basics of API testing and its significance4. Variable Management- Managing environment, global, and collection variables- Utilizing scripting snippets for dynamic data5. Building Testing Workflows- Creating effective testing workflows for comprehensive testing- Utilizing the Collection Runner for test execution- Introduction to Postbot for automated testing6. Advanced Testing- Contract Testing for ensuring API contracts- Using Mock Servers for effective testing- Maximizing productivity with Collection/Workspace templates- Integration Testing and Regression Testing strategies7. Automation with Postman- Leveraging the Postman CLI for automation- Scheduled Runs for regular testing- Integrating Postman into CI/CD pipelines8. Performance Testing- Demonstrating performance testing capabilities (showing the desktop client)- Synchronizing tests with VS Code for streamlined development9. Exploring Advanced Features - Working with Multiple Protocols: GraphQL, gRPC, and more
Join us for this workshop to unlock the full potential of Postman for API testing, streamline your testing processes, and enhance the quality and reliability of your software. Whether you're a beginner or an experienced tester, this workshop will equip you with the skills needed to excel in API testing with Postman.
Testing Web Applications Using Cypress
TestJS Summit - January, 2021TestJS Summit - January, 2021
173 min
Testing Web Applications Using Cypress
WorkshopFree
Gleb Bahmutov
Gleb Bahmutov
This workshop will teach you the basics of writing useful end-to-end tests using Cypress Test Runner.
We will cover writing tests, covering every application feature, structuring tests, intercepting network requests, and setting up the backend data.
Anyone who knows JavaScript programming language and has NPM installed would be able to follow along.
Best Practices for Writing and Debugging Cypress Tests
TestJS Summit 2023TestJS Summit 2023
148 min
Best Practices for Writing and Debugging Cypress Tests
Workshop
Filip Hric
Filip Hric
You probably know the story. You’ve created a couple of tests, and since you are using Cypress, you’ve done this pretty quickly. Seems like nothing is stopping you, but then – failed test. It wasn’t the app, wasn’t an error, the test was… flaky? Well yes. Test design is important no matter what tool you will use, Cypress included. The good news is that Cypress has a couple of tools behind its belt that can help you out. Join me on my workshop, where I’ll guide you away from the valley of anti-patterns into the fields of evergreen, stable tests. We’ll talk about common mistakes when writing your test as well as debug and unveil underlying problems. All with the goal of avoiding flakiness, and designing stable test.