The one thing Vitest has better support than Jest
TLDR In this post, we explore the limitations of Jest in regards to jsdom-worker and compare it with Vitest, which supports it out-of-the-box. We discuss the challenges of mocking shared workers, the performance implications, and the complexity involved in testing applications that rely on them. By understanding these limitations and exploring alternatives, developers can make informed decisions about their testing strategies and improve the overall quality of their applications. Introduction Testing has been a key focus of mine since I started writing code. Once I discovered test automation, it became clear to me that part of my connection to testing comes from the sense of safety it provides. Tests act as a safety net not only for myself, but also for the team members I collaborate with. They help communicate my thought process, clarify different scenarios, and even expose missing or invalid cases I hadn’t considered. Among the various aspects of testing, the idea of "testing all the things" stood out to me especially when it comes to code that depends on third-party libraries or external APIs. In this post, I want to explore the relationship between the challenges of dealing with external dependencies and the role of testing. Web workers Web workers were created in 2009 and according to caniuse.com, they're widely supported by modern browsers. In their early days, the proposed web workers were developed by a working group that supported by w3c. As a simple analogy, web workers act as a thread would act in a programming language like Java. The main thread launches the web worker through the new operator and it will be created and wait for the task to be executed. From there, a relationship between the main script and the worker is created. This does not mean that from here the browser will off-load all the heavy computation automatically. It is still the responsibility of the developer to decide which work should be delegated, and that's where the catch is. We need to control it in order to make it testable. So what workers have two types of workers the web worker itself and the second type is the shared worker. The web worker is a worker that works at the context context page so it is attached to a single page whereas they shared worker is a worker that is possible to be used across pages. This is where the complexity starts to power up in regards to testing because what workers require async communication that needs to be faked in the test case. What is a worker? A web worker is a JavaScript script that runs in the background, separate from the main thread of a web application. It allows for concurrent execution of tasks, enabling developers to offload heavy computations or long-running processes without blocking the user interface. This is particularly useful for improving app performance and responsiveness. What is a Shared Worker? A shared worker is a type of web worker that can be accessed by multiple scripts running in different windows, tabs, or iframes. This allows for shared state and communication between different parts of an application, making it useful for scenarios where multiple components need to coordinate or share data. Discussion: should I mock it? One of the first options that comes to mind is to mock the shared worker, however, this is not a good idea. The reason for that is that the shared worker is a complex object that has its own lifecycle and state. Mocking it would require a deep understanding of how it works and how it interacts with the rest of the application. Leading to a fragile test for refactoring. Another option is to stub it with a simple implementation that does not require a deep understanding of the shared worker. This is a better option, as it allows you to test the application without having to worry about the complexities of the shared worker. Jest Jest is a popular JavaScript testing framework that provides a robust set of features for unit and integration testing. It is widely used in the React ecosystem and has built-in support for mocking, making it a go-to choice for many developers. Despite of its strengths, Jest has limitations when it comes to mocking shared workers, which can be a significant drawback for applications that rely on them. Why Jest Doesn't Support Shared Workers Jest has a powerful mocking API, but it may not be sufficient for shared workers due to their complexity and the need for cross-thread communication. In fact, the project jsdom-worker, is the project that offers the possibility to use workers in a test environment, but it is not the default behavior of Jest. It's support stops there, for shared workers it will not work. In an issue created in 2022, the question made by evlist was target at this lack of support on shared workers, until today no response was given on the support for it. I tried to create the utilities needed for it

TLDR
In this post, we explore the limitations of Jest in regards to jsdom-worker and compare it with Vitest, which supports it out-of-the-box. We discuss the challenges of mocking shared workers, the performance implications, and the complexity involved in testing applications that rely on them. By understanding these limitations and exploring alternatives, developers can make informed decisions about their testing strategies and improve the overall quality of their applications.
Introduction
Testing has been a key focus of mine since I started writing code. Once I discovered test automation, it became clear to me that part of my connection to testing comes from the sense of safety it provides. Tests act as a safety net not only for myself, but also for the team members I collaborate with. They help communicate my thought process, clarify different scenarios, and even expose missing or invalid cases I hadn’t considered.
Among the various aspects of testing, the idea of "testing all the things" stood out to me especially when it comes to code that depends on third-party libraries or external APIs.
In this post, I want to explore the relationship between the challenges of dealing with external dependencies and the role of testing.
Web workers
Web workers were created in 2009 and according to caniuse.com, they're widely supported by modern browsers. In their early days, the proposed web workers were developed by a working group that supported by w3c.
As a simple analogy, web workers act as a thread would act in a programming language like Java. The main thread launches the web worker through the new operator and it will be created and wait for the task to be executed. From there, a relationship between the main script and the worker is created.
This does not mean that from here the browser will off-load all the heavy computation automatically. It is still the responsibility of the developer to decide which work should be delegated, and that's where the catch is. We need to control it in order to make it testable.
So what workers have two types of workers the web worker itself and the second type is the shared worker. The web worker is a worker that works at the context context page so it is attached to a single page whereas they shared worker is a worker that is possible to be used across pages. This is where the complexity starts to power up in regards to testing because what workers require async communication that needs to be faked in the test case.
What is a worker?
A web worker is a JavaScript script that runs in the background, separate from the main thread of a web application. It allows for concurrent execution of tasks, enabling developers to offload heavy computations or long-running processes without blocking the user interface. This is particularly useful for improving app performance and responsiveness.
What is a Shared Worker?
A shared worker is a type of web worker that can be accessed by multiple scripts running in different windows, tabs, or iframes. This allows for shared state and communication between different parts of an application, making it useful for scenarios where multiple components need to coordinate or share data.
Discussion: should I mock it?
One of the first options that comes to mind is to mock the shared worker, however, this is not a good idea. The reason for that is that the shared worker is a complex object that has its own lifecycle and state. Mocking it would require a deep understanding of how it works and how it interacts with the rest of the application. Leading to a fragile test for refactoring.
Another option is to stub it with a simple implementation that does not require a deep understanding of the shared worker. This is a better option, as it allows you to test the application without having to worry about the complexities of the shared worker.
Jest
Jest is a popular JavaScript testing framework that provides a robust set of features for unit and integration testing. It is widely used in the React ecosystem and has built-in support for mocking, making it a go-to choice for many developers.
Despite of its strengths, Jest has limitations when it comes to mocking shared workers, which can be a significant drawback for applications that rely on them.
Why Jest Doesn't Support Shared Workers
Jest has a powerful mocking API, but it may not be sufficient for shared workers due to their complexity and the need for cross-thread communication.
In fact, the project jsdom-worker, is the project that offers the possibility to use workers in a test environment, but it is not the default behavior of Jest. It's support stops there, for shared workers it will not work.
In an issue created in 2022, the question made by
evlist was target at this lack of support on shared workers, until today no response was given on the support for it. I tried to create the utilities needed for it to work, however, its shared state complicate testing, as it requires management of the worker's lifecycle and communication channels.
Recently I gave up on trying to code myself the support and contribute back due to priorities constraint.
The code is still available on GitHub. The approach I took was to take the json-tool project as a real example and reverse engineer the code based on the web worker. This repository snapshot depicts the state were the script jsdom.js was copied and pasted from jsdom-worker project in an attempt to
understand how it worked.
In the next section, let's see what vitest offers in regards to web workers and how it interacts with
jest.
Steps to get partial support in jest:
- install jest
- install jsdom-worker
- update jest config to use jsdom-worker
Vitest
Vitest on the other hand, appeared with out-of-the-box support for shared workers. It is a testing framework that is designed to be fast and efficient, with a focus on modern JavaScript features. It has built-in support for shared workers, making it easier to test applications that rely on them.
This is an advantage over Jest, as it allows developers to write tests for shared workers without the need for complex workarounds or additional libraries.
In the package web-worker the shared worker is implemented in addition to the worker.
Steps to get full support in vitest:
- install vitest
Conclusion
This post aimed at providing a comprehensive overview of the challenges and solutions related to testing shared workers in Jest and Vitest. By understanding these limitations and exploring alternatives, developers can make informed decisions about their testing strategies and improve the overall quality of their applications.
I do encourage you to share your experiences with shared workers and testing frameworks in the comments section. Your insights can help others navigate similar challenges and enhance their testing practices.