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.
This talk has been presented at Node Congress 2024, check out the latest edition of this JavaScript Conference.
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.
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.
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.
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.
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.
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.
BUN is a modern all-in-one JavaScript runtime environment that achieves new levels of performance. It includes BUN dev, a fast front-end dev server, BUN install, a speedy package manager, and BUN run, a fast package runner. BUN supports JSX, has optimized React server-side rendering, and offers hot module reloading on the server. The priorities for BUN include stability, node compatibility, documentation improvement, missing features in BUN install, AST plugin API, native Windows support, Bundler and Minifier optimization, and easier deployment to production. BUN's AST plugin API allows for bundle-time JavaScript execution and embedding code, potentially inspiring new frameworks.
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
La web ha evolucionado. Finalmente, también lo ha hecho el testing. Cypress es una herramienta de testing moderna que responde a las necesidades de testing de las aplicaciones web modernas. Ha ganado mucha popularidad en los últimos años, obteniendo reconocimiento a nivel mundial. Si has estado esperando aprender Cypress, ¡no esperes más! Filip Hric te guiará a través de los primeros pasos sobre cómo empezar a usar Cypress y configurar tu propio proyecto. La buena noticia es que aprender Cypress es increíblemente fácil. Escribirás tu primer test en poco tiempo y luego descubrirás cómo escribir un test de extremo a extremo completo para una aplicación web moderna. Aprenderás conceptos fundamentales como la capacidad de reintentar. Descubre cómo trabajar e interactuar con tu aplicación y aprende cómo combinar pruebas de API y de UI. A lo largo de todo este masterclass, escribiremos código y realizaremos ejercicios prácticos. Saldrás con una experiencia práctica que podrás aplicar a tu propio proyecto.
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
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.
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
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.
Comments