Qué hay de nuevo en el Node.js Test Runner y por qué es revolucionario

Rate this content
Bookmark

El nuevo test runner de Node es bastante genial pero todavía no mucha gente lo está utilizando. En mi charla, te mostraré todas las cosas interesantes que puede hacer, incluyendo algunas características en las que trabajé. Echaremos un vistazo bajo el capó de Node para ver cómo funcionan las simulaciones y cómo usarlas. También hablaré sobre lo que viene para el runner y qué esperar en el futuro. ¡Prepárate para mejorar tu juego de pruebas con aserciones nativas y mantener las cosas funcionando rápido!

Lucas Santos
Lucas Santos
17 min
04 Apr, 2024

Video Summary and Transcription

El Node.js Test Runner se presenta como una mejor alternativa a Jest, ofreciendo más flexibilidad y mejor rendimiento. Admite TypeScript de forma nativa y proporciona una visualización completa del conjunto de pruebas. El test runner tiene soporte nativo para la cobertura de código y las próximas características incluyen simulación de módulos y mejor filtrado. Cambiar al test runner es simple y ayuda al crecimiento de la comunidad.

Available in English

1. Introducción al Node.js Test Runner

Short description:

Hola a todos. Hoy vamos a hablar sobre el Node.js Test Runner. Soy Luca Santos, un ingeniero de software senior en OpenVault. Puedes contactarme en Twitter e Instagram en elsantos.dev.

Hola a todos. Hoy vamos a hablar sobre el Node.js Test Runner. Así que primero que nada, me voy a presentar. Mi nombre es Luca Santos. Soy uno de los ingenieros de software senior en OpenVault hoy en día. Vivo en Suecia. Soy originario de Brasil. Y puedes contactarme en cualquiera de mis redes sociales. Básicamente, están las que están en la parte inferior. Twitter.elsantos.dev, Instagram.elsantos.dev. Ya sabes, entiendes la idea. Luca es un nombre muy común en Brasil. Así que básicamente, tuve que elegir DNS sobre Nix en las redes sociales. Así que solo coloca el nombre de la red social seguido de .elsantos.dev. O si tienes dudas sobre alguna red social en la que quieras hablar conmigo, solo .elsantos.dev te llevará a mi página principal donde está todo. ¿De acuerdo? Estoy totalmente abierto a hablar de cualquier cosa. Así que contáctame y será muy agradable.

2. Los beneficios del Node.js Test Runner

Short description:

Mi objetivo con esta charla es hacer que dejes de usar Jest por algo mejor, el Node.js test runner. Jest está desactualizado y tiene limitaciones. El Node.js test runner se mejora constantemente y ofrece más flexibilidad. Los test runners actuales son difíciles de configurar, especialmente para TypeScript, y a menudo requieren bibliotecas adicionales que pueden ralentizar tu proyecto. También carecen de interoperabilidad y pueden ser inflexibles.

A continuación, compartiré mi objetivo en esta charla contigo. ¿Cuál es el objetivo que tengo con esta charla? Es hacer que dejes de usar Jest al final. Así de simple. No odio Jest. De hecho, lo uso mucho. Pero he tenido mi parte justa de problemas. Y creo que es hora de seguir adelante, ¿verdad? Creo que es hora de que necesitamos algo nuevo, algo mejor. Jest es muy antiguo, ¿verdad? Es muy bueno, pero el tiempo ha pasado, ¿verdad?

Así que voy a hacer esto. Te voy a presentar algo que posiblemente sea mejor. Pero ¿por qué posiblemente mejor? Bueno, porque el Node.js test runner todavía se está mejorando activamente. Así que hay muchas cosas que están sucediendo. Hay muchas cosas que ya tenemos, pero aún faltan muchas cosas. Así que puedes ayudar si quieres, ¿de acuerdo?

Pero primero, ¿qué es malo en el entorno actual? ¿Por qué necesitamos otro test runner? ¿No es suficiente lo que tenemos hoy? Básicamente, lo primero es que son demasiado difíciles de configurar, especialmente para TypeScript. Y hacen muchas cosas. Configurar Jest es un dolor. Es un archivo de configuración muy grande. Hacen muchas cosas. Hacen transformaciones, hacen análisis, hacen movimientos, hacen aserciones, tienen cobertura. Es simplemente demasiado. Y esto los hace lentos, ¿verdad? Porque, bueno, es demasiado. Y luego tienes un concepto que llaman yall, que básicamente es otra biblioteca más en tu proyecto. Porque los runners, en mi opinión, deberían ser una parte de tu entorno de ejecución. No deberías poder instalar, no deberías instalar otra biblioteca para tener un runner. Y recuerda, cada otra biblioteca, cada paquete que se instala en tu proyecto es un code que no mantienes, pero en el que aún dependes, ¿verdad? Así que si algo sucede, pagarás el precio. Y los test runners parecen no querer interoperar entre sí. Se aseguran de que solo puedas usarlos a ellos y a nada más. Así que es muy difícil cambiar de uno a otro. Son cosas completamente diferentes. La mayoría de ellos son bastante dogmáticos. Así que son o muy extensibles o no extensibles en absoluto.

3. Ventajas del Node.js Test Runner

Short description:

No hay un punto intermedio o extensibilidad con los test runners existentes, especialmente para TypeScript. O carecen de flexibilidad o requieren bibliotecas adicionales. El Node.js test runner se destaca como una solución integrada que es rápida, fácil de usar y funciona perfectamente con Node.js. Admite aserciones nativas y se puede integrar con otros procesadores de pruebas. Proporciona resultados consistentes en todo tu proyecto.

No hay un punto intermedio o algo que puedas extender, o si no quieres extender. Básicamente, es difícil, ya sabes, hacer lo que quieres a menos que tengas algo súper extensible pero a la vez súper difícil de usar como Jest o algo que no sea extensible en absoluto. Si quieres TypeScript, como TypeScript es el némesis de todos los test runners porque lo arruinan por completo. Y si quieres TypeScript, puedes hacer un test runner nativo de TypeScript, que no hay muchos hoy en día, o puedes tener otra biblioteca encima de un proyecto que necesitas instalar para poder ejecutar esto, ¿verdad, completamente?

Y hay tantos de ellos, test runners en Spawnlight, RATS, hay muchos de ellos. Y básicamente es un gran bloat porque no agregan muchas cosas al ecosistema. No interoperan entre sí. Básicamente, son lo mismo con pequeñas mejoras de uno a otro. Pero luego entra en escena el test runner de Node.js. El test runner de Node.js no es tan nuevo. Fue agregado por Colin el 8 de abril de 2022. Y esta fue la versión inicial, como la CLI. Y luego uno de mis antiguos colegas en Microsoft, agregó un analizador TAP. TAP significa test anything protocol. Hablaremos de eso un poco más tarde. Pero te permitía interoperar el test runner con otros test runners, otros procesadores de pruebas en realidad. Luego se estabilizó rápidamente. Aproximadamente cuatro meses después, se hizo estable en Node 20. Así que puedes usarlo en Node 20 y es estable para producción. Puedes usarlo normalmente y libremente.

Pero, ¿por qué es diferente de los demás y por qué lo recomiendo tanto? En primer lugar, es integrado, sin YL, ¿verdad? Así que no es otra biblioteca encima de un proyecto. Es bastante rápido, muy rápido, para ser honesto. Y no necesitas configurar nada. En realidad, no hay rituales que necesites hacer para configurarlo. Funciona perfectamente en Node.js. Puedes usar aserciones nativas si quieres, pero reconozco que la biblioteca de aserciones nativas no es tan increíble como otras, pero puedes cambiar las bibliotecas a cualquier otra biblioteca de aserciones. Genera el protocolo TAP, por lo que es fácil de integrar. Acepta otros reporteros de pruebas también. Siempre puedes usar las características más actualizadas de Node.js porque siempre está actualizado con las características de Node.js. Lo mejor de todo es que tiene consistencia en todo tu proyecto.

4. Ejecutando pruebas con el Node.js Test Runner

Short description:

El test runner de Node.js está integrado, es fácil de usar y funciona perfectamente con Node.js. Admite TypeScript de forma nativa y se puede extender con otras bibliotecas de aserciones. La ejecución de pruebas es sencilla y la salida incluye información completa sobre los conjuntos de pruebas, las pruebas canceladas y las pruebas omitidas.

Entonces tienes miles de proyectos, todos van a estar usando el mismo test runner y el mismo test runner de Node.js que está construyendo el tiempo de ejecución, ¿verdad? Entonces te vas a basar en el propio tiempo de ejecución. No hay polyfills que necesites hacer, como cosas de Babel y blah, blah, blah. Y tiene soporte experimental para la cobertura de código y por ahora, se está volviendo estable a lo largo de los años y también otros reporteros. Y admite TypeScript de forma nativa. Es muy fácil hacer que se ejecute como ejecutarías TypeScript en Node.js normalmente, ¿verdad? Así que empecemos. Permíteme mostrarte cómo funciona. Primero, declaramos la función que queremos probar y luego creamos nuestra prueba, ¿verdad? Así que vamos a desglosar eso un poco. Primero escribimos la prueba. Simplemente importamos nuestras bibliotecas, importamos el describe y it. Puedes usarlo directamente con una prueba. Prefiero usarlo así porque creo que es mucho más fácil de leer. Luego importamos la función de aserción, la biblioteca de aserciones. Es la misma que usamos en otras bibliotecas. Es un poco diferente, no es tan fácil de leer pero me gusta usar la nativa porque es nativa. Luego importamos nuestra función que queremos probar y luego la prueba es básicamente la misma prueba que escribiríamos en cualquier otro test runner. Así que describimos el nombre del conjunto de pruebas y luego it y luego la prueba que quieres ejecutar y luego tienes assert y eso es básicamente todo. Si no quieres usar describe o cualquier otra cosa puedes importarlo directamente como prueba desde no test. Y eso es lo que te dije, es un poco más verboso pero funciona igual. Y las bibliotecas de aserciones son manejadas por el módulo de la biblioteca de aserciones, que está integrado pero reconozco que esta no es realmente la mejor. Probablemente me gustaría decir que deberías usarla porque es nativa, pero no es la mejor biblioteca integrada allí. Así que puedes usar cualquier otra que quieras como Chai u otra cosa que quieras usar. Básicamente solo la importas, lo único que debes asegurarte es que la biblioteca de aserciones lance cuando haya un error. Cuando hay un error, lanza y listo. Y como hice aquí, simplemente importé Chai desde, expect de Chai y luego funciona normalmente. Lo importante es que la biblioteca de aserciones está completamente desvinculada del runner. Así que puedes ejecutar lo que quieras, es lo suficientemente extensible para hacerlo. Y cuando ejecutas, básicamente estás ejecutando node --test y el nombre de tu archivo de prueba. Node simplemente agrega el comando de prueba al comando node y luego ejecuta tus archivos de prueba. Te dará una salida en formato TAP.

5. Mocking and Controlling Test Behavior

Short description:

El test runner de Node.js admite una visualización completa del conjunto de pruebas, incluyendo pruebas canceladas, omitidas y por hacer. También ofrece capacidades de simulación potentes para funciones, getters, setters y métodos. Además, ofrece soporte incorporado para simular temporizadores y fechas, lo que te permite controlar y manipular fácilmente la funcionalidad relacionada con el tiempo en tus pruebas.

En primer lugar, puedes ver todo, como todos tus conjuntos de pruebas, y luego puedes ver las pruebas canceladas, las pruebas omitidas, también es una característica compatible. Puedes ver las pruebas por hacer, también es una característica compatible.

Y luego tenemos las simulaciones. Las simulaciones son una de las mejores y más importantes características de una prueba, en realidad. Para mí, es la mejor característica de Jest, las simulaciones. Pero Node también las tiene. Node admite la simulación de algunas de las estructuras integradas. Por ejemplo, mock Fn es similar a Jest Fn, como simulaciones y funciones, solo una función espía. También simula getters, setters, y actualmente también puede simular métodos, ¿verdad?

Pero también hay otras dos estructuras complejas que te voy a mostrar. La primera de esas estructuras es la fecha, en realidad, en realidad los temporizadores. Esto fue agregado por un buen amigo mío, Eric. Básicamente, simula cosas como setTimeout, setInterval y cosas así. Entonces, básicamente, lo que necesitas hacer es crear tu prueba, y luego creamos una función, que es una función espía, y luego habilitamos la funcionalidad de simulación de temporizadores, diciendo qué biblioteca, qué API queremos simular. Entonces, básicamente, setTimeout es el que queremos simular. Y luego simplemente establecemos un tiempo de espera de, por ejemplo, 99999 algo. Y luego vamos a afirmar que el temporizador aún no se ha llamado porque el temporizador no ha sido ejecutado. Entonces tenemos que hacer que ese temporizador se ejecute, y luego podemos afirmar nuevamente y decir, eh, ahora se ha llamado este tiempo. Y podemos restablecer el temporizador a su estado original.

También puedes importar los temporizadores simulados directamente desde el directorio de pruebas de Node. No necesitas importarlo como en el contexto como lo estamos usando aquí, como context.mocks. Puedes importarlo directamente desde la prueba. También funciona, básicamente como lo estamos haciendo aquí. Y la siguiente estructura compleja fue agregada por su servidor, y son las fechas. Esta es una característica en la que personalmente he trabajado y que se basa en estructuras anteriores como setTimeout e setInterval, te permite simular el objeto de fecha. Entonces, simular fechas en Node es, lo único que tenemos que hacer diferente es habilitar las simulaciones para usar la API de fecha. Y luego iniciamos la simulación. Comenzará con la época de Unix, es decir, el 1 de enero de 1970. Y luego podemos avanzar en la simulación, y luego podemos afirmar que la nueva fecha será esa fecha más 9999 milisegundos. Es algo muy útil si quieres lidiar con mensajes y cosas así.

6. Code Coverage and TypeScript Support

Short description:

El test runner de Node.js tiene soporte nativo para la cobertura de código, utilizando la función de cobertura incorporada de V8. Puedes cambiar los reporteros de cobertura y generar informes en diferentes formatos o archivos. TypeScript es totalmente compatible, lo que te permite ejecutar archivos TypeScript sin ninguna configuración adicional. El test runner también ofrece características como señales de aborto, saltar pruebas, marcar pruebas específicas, ganchos del ciclo de vida y filtrado de patrones de nombre. El futuro de las pruebas en Node.js incluye el próximo soporte para la simulación de módulos en el test runner.

Así que lo usamos mucho. Y la cobertura de código es el siguiente paso para las compatibilidades de las que quiero hablarte. El test runner de Node.js tiene soporte nativo. Simplemente pasas la bandera, que es experimental test coverage. Va a utilizar la función de cobertura incorporada de V8 para darte una salida como esta. Te dará el comando que vamos a ejecutar y estas serán las pruebas que se van a ejecutar. Luego tenemos la salida TAP habitual que tenemos en el lateral, y luego tenemos el inicio del informe de cobertura. Como puedes ver, en el resultado de la cobertura, hay dos líneas que no fueron cubiertas, que son las que lanzamos aquí en nuestra función. Así que funciona como se esperaba, ¿verdad? También puedes cambiar los reporteros de cobertura. Puedes usar diferentes reporteros y/o generar informes directamente en archivos, utilizando el test reporter o el test reporter destination. Actualmente, el test runner nativo admite estos reporteros. Puedes usar los reporteros spec.tap, lcol y JUnit también, de forma nativa, solo tienes que ponerlos en el test reporter, igual y el nombre del reportero.

Pero ahora hablemos de TypeScript, que es lo que más me gusta. Un poco de información adicional aquí, pero no sé si sabes todo esto, pero Node ya te permite compilar TypeScript sobre la marcha utilizando importers, ¿verdad? Anteriormente, los importers se llamaban loaders, y son funciones que se ejecutan antes de que se cargue un módulo y también se pueden utilizar para transformar un módulo antes de importarlo. Babel tiene loaders, Jest tiene loaders, muchas otras herramientas que utilizamos tienen loaders porque puedes importar el módulo y luego va a cambiar el archivo en el que estás y luego va a ejecutar el archivo en el que estás, ¿verdad? Esto significa que también puedes ejecutar TypeScript porque simplemente puedes importar un archivo TypeScript y luego convertirlo a JavaScript, ¿verdad? Y los importers comunes que tenemos hoy en día son ts-node, ts-sex y ts-build. También puedes crear el tuyo propio si quieres, si no quieres utilizar ninguna biblioteca externa. Me gusta ts-sex, creo que es uno de los mejores que hay. Y para el soporte de TypeScript, solo he cambiado el archivo que teníamos antes. Solo he añadido algunos tipos y luego podemos ejecutarlo con import ts-sex y básicamente el archivo ts index.ts, y luego boom, magia, ¿verdad? Pero, ¿qué pasa si te dijera que en realidad puedes usar esto para ejecutar el test runner? Así que el soporte de TypeScript, solo tomamos nuestra extensión de archivo anterior y le añadimos --test. Así que boom, se ejecuta, nada más, como magia. Eso es todo, todo se ejecuta, no hay configuración, nada, solo ejecutamos con cosas nativas, ¿verdad? Y cuando ves esto, como ese archivo de configuración de jazz de 50 líneas que has estado manteniendo durante los últimos cinco años, verás que esto es bastante agradable porque ya no tienes que mantener TypeScript, así que es súper, súper agradable. Y hay otras características compatibles para el test runner de Node, por lo que en realidad puedes abortar pruebas a través de señales de aborto. Puedes saltarte la prueba, como dije, con it skip o it to do para una prueba que aún está por hacer. Puedes marcar una prueba específica que quieres ejecutar, así que con it only, es divertido, súper agradable. Y también tenemos ganchos del ciclo de vida como lo hace Jest con before, after, before each, after each y cosas así. Y también puedes filtrar el patrón de nombre a través de rejects. Ahora puedes hacerlo, creo que Node 21 ha añadido el soporte para globs, así que ahora puedes añadir globs en los nombres de archivo y tienes un modo de observación, que es experimental. Pero el futuro de las pruebas en Node.js, y curiosamente, Colin mismo tiene una lista de lo que quiere para el test runner de Node.js. Lo primero que quería mostrarte es la simulación de módulos. Básicamente, la simulación de módulos también se está implementando en el test runner.

7. Próximas características y conclusión

Short description:

Las próximas características en el test runner incluyen la simulación de módulos, mejor filtrado con globs, pruebas de snapshot, soporte de mapas de origen y más mocks. Puedes participar contribuyendo o brindando comentarios. Cambiar al test runner es simple y ayuda al crecimiento de la comunidad. Conéctate conmigo en las redes sociales para obtener más información.

Es un poco diferente de lo que esperaría, pero la idea de que realmente puedas simular todo el módulo y no solo los métodos o archivos y cosas así, puedes simular realmente muchas cosas. Es súper genial. Luego tenemos un mejor filtrado, que es justo lo que acabo de decir. Entonces, básicamente, puedes ejecutar por patrón de nombre de prueba, ahora creo que puedes ejecutar con globs y aún se está mejorando. No es lo mejor, pero lo será en el futuro. Luego también podemos tener más importers, más reporteros y pruebas de snapshot. Las pruebas de snapshot son algo en lo que quería trabajar, pero es una cosa de biblioteca de aserciones. Ok, así que se agregó brevemente durante unas pocas semanas en el runner en el pasado, pero se eliminó debido a algunos problemas de almacenamiento, como problemas de almacenamiento que tuvimos con el runner, y luego se eliminó. Pero realmente quiero agregar esto de nuevo porque las pruebas de snapshot son súper, súper agradables. Luego tenemos soporte de mapas de origen, que básicamente habla por sí mismo, y más, más mocks. Quiero crear, creo que es importante que tengamos mocks para todo, no solo mocks de módulos. Personalmente, quiero trabajar en los mocks de rendimiento. Quiero trabajar en otros mocks que podamos crear a partir de los módulos nativos y las pruebas nativas de Node. Ok, eso es una de las cosas que realmente me gusta. Y al final de esto, espero que tengamos la caída definitiva, supongo. Pero eso es solo una broma. Sé que llevará un tiempo, pero por ahora, podemos seguir usándolo tal como está hoy. Pero ¿puedes participar en esto, verdad? Oh, volvió. Así que puedes participar en esto, ¿verdad? Lo primero es que la documentación siempre es un buen lugar para comenzar. Si quieres saber cosas sobre Test Runner, ve allí, intenta documentar algunas cosas. También puedes contribuir al código, tal vez hacer feliz a Colin con su lista de deseos. No sé. Tal vez seas tú quien le dé este regalo. O simplemente úsalo, brinda comentarios, porque es muy agradable tener a alguien que brinde comentarios sobre los módulos y las APIs y las cosas que realmente están en la línea de producción. Cosas que la gente está usando de verdad, lo que está ahí. Comienza a cambiar tus proyectos a esto, ayuda al crecimiento de la comunidad. No es difícil cambiar una cosa por la otra. En realidad, es bastante simple cambiar de un runner a otro, ¿de acuerdo? Espero haberte convencido. Y muchas gracias por el tiempo que has estado aquí conmigo hoy. Si quieres hablar conmigo, simplemente ve a cualquiera de mis redes sociales. Si quieres ver esta agradable charla, ve a este código QR o a este enlace que estoy dejando aquí. Y espero que te haya gustado. Nos vemos pronto. ♪♪♪

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

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
Node.js Compatibility in Deno
Node Congress 2022Node Congress 2022
34 min
Node.js Compatibility in Deno
Can Deno run apps and libraries authored for Node.js? What are the tradeoffs? How does it work? What’s next?
Bun, Deno, Node.js? Recreating a JavaScript runtime from Scratch - Understand magic behind Node.js
Node Congress 2023Node Congress 2023
29 min
Bun, Deno, Node.js? Recreating a JavaScript runtime from Scratch - Understand magic behind Node.js
Bun, Deno, and many other JavaScript runtimes have been hyped, but do you know why? Is it that easy to make a runtime from scratch?

I've been researching the secret behind Node.js' power and why there are so many new JavaScript runtimes coming up. Breaking down each key component used on Node.js I've come to interesting conclusions that many people used to say whereas in practice it works a bit differently.

In this talk, attendees will learn the concepts used to create a new JavaScript runtime. They're going to go through an example of how to make a JavaScript runtime by following what's behind the scenes on the Node.js project using C++. They'll learn the relationship between Chrome's V8 and Libuv and what makes one JavaScript runtime better than others.

This talk will cover the following topics:
- What's a JavaScript Engine - V8
- Why Node.js uses Libuv
- How to create a JS Runtime from scratch
Eval all the strings! - Hardened JavaScript
Node Congress 2023Node Congress 2023
8 min
Eval all the strings! - Hardened JavaScript
This talk is about SecureEcmaScript and Compartments which are TC39 proposals, and I'm working on tooling to make these concepts usable with people championing those proposals.
This is a first-hand account of the future of JavaScript security.
SES + tooling (LavaMoat or Endo) is making limiting access to network, fs, core modules or globals possible on a per-package basis.
I want to show how they work, what possibilities they open and how to make that future happen today with some effort.
To me this is the final step in securing npm supply chain - even if a package gets taken over by bad actors, it won't be able to hurt me.
The Future of JavaScript Runtimes
Node Congress 2022Node Congress 2022
34 min
The Future of JavaScript Runtimes
JavaScript was born in the browser, Node brought it to the server embracing unix primitives and async I/O and lately Cloudflare Workers & Deno Deploy have brought it to the edge. Let’s take a look at where JavaScript runtimes are heading and how it will shape the software we write.
Roll you own JavaScript runtime
Node Congress 2023Node Congress 2023
21 min
Roll you own JavaScript runtime
In this talk, we’ll create a small JavaScript runtime from scratch in Rust. We’ll leverage the same ecosystem of components that Deno uses to show that rolling a bespoke runtime fitting your needs is simple and fun in 2023