jest vs jasmine: main differences
When talking about unit testing, Karma + Jasmine are often mentioned together. Recently, people have started talking about switching to Jest.
What’s the difference, why switch, and why is Jest standalone while Karma is always paired with Jasmine?
First of all, let me say that there are many ways to test code, as well as numerous frameworks and libraries. We’ll explore how they differ from Jest and Jasmine towards the end of the article. For now, let’s assume that only two solutions exist.
Key advantages of Jest, often praised on the first page of Google:
- Fewer configs
- Code coverage out of the box
- Nice documentation
It’s not convincing yet for someone who uses Google and Stack Overflow, and doesn’t mind creating one JSON file. Especially since in Jest, you need to use additional packages if you’re working with TypeScript, and there are other side effects. In the end, you still need to create a config…
The real differences that might make you consider switching:
- Works without a browser
- Multithreading
- Snapshots
Articles for basic understanding: jasmine+ karma, jest
Introduction
Everyone constantly hears Karma + Jasmine, but why always together? What do they each do on their own?
Jasmine
Jasmine is a testing framework written in Node.js. It provides functions like it
, describe
, and expect
, which are responsible for running tests in the right order and collecting test results.
However, to run a web application or part of it, you need an HTML file and a browser to display it, such as Chrome, headless Chrome, Firefox, or PhantomJS….
But how to do it? You would need to create an HTML file, include the JavaScript, open it in the browser, run the tests, view the results, fix code/tests, and repeat over again….
Running Jasmine tests once on an application that doesn’t interact with the DOM is easy. However, running tests on every code change in a live browser (so that all DOM APIs, like clicks, work) is more complex. That’s where Karma comes in. It handles this setup and process, making it much easier to run tests automatically on code changes within a browser. Here’s how it looks:
Jest
Jest is another framework that provides the same essential functions for testing, like it
, describe
, and others (with different names than Jasmine but the same purpose). The key difference is that Jest works entirely without a browser because it uses the jsdom library to emulate all DOM interactions in Node.js. And all the functionality Karma provides—restarting, gathering stats—is built directly into Jest.
As a result, all test interactions happen in the console, without opening and closing browsers like with Jasmine.
Clarification: If you run Jasmine on PhantomJS, browsers won’t visibly open and close either. However, there will still be interactions with something outside the test framework itself.
Hooray, we’ve clarified the terminology — now let’s move on to the main topic!
Multithreading
Why is multithreading needed? To run tests in parallel, which means faster!
It’s well-known fact that Karma doesn’t have multithreading. Update: Apparently, it does have some form of it!
Jest can run each test file in parallel, which speeds up the testing process. By default, the number of threads equals the number of CPU cores, but you can adjust this with the maxWorker
option.
Within a single test file, tests are executed sequentially, though you can parallelize them within the file too, but this feature still has bugs.
Be careful when running tests in parallel — remember that they should be independent! In fact, tests should always be independent, but this is especially important when they’re being executed concurrently.
Snapshots
A snapshot is a textual “screenshot” of the resulting HTML (a fragment of the DOM tree at a specific moment in time, essentially just a string). It allows you to verify that the correct strings have been rendered in the correct divs
and that the right parameters were passed to components. A snapshot is useless on its own; it’s always compared to the previous snapshot, and if they differ, it alerts the developer to make a decision.
Snapshots are more popular in React, although I don’t see a fundamental difference for Angular. In my opinion, snapshots are a controversial idea for broad use because they become invalidated with every template change (including intentional ones), increasing the chances that potential errors will be ignored by the developer.
That said, there are cases where snapshots are better than regular unit tests.
Can you add snapshots to Karma with Jasmine? Yes, but you need to set it up for both. Karma handles saving the snapshots, while Jasmine compares them. I found a package for this (there are likely more), but the author mentions it works with two significant caveats, which aren’t ideal. If you’re using Karma but want snapshots, it’s simpler to run both Karma and Jest together instead of forcing them into the same system.
Working via the console
As I mentioned earlier, with Jest, there are no browsers popping up! You run the tests in the console, read the results in the console, and there’s no need to build and package the app into HTML. Everything runs faster by default. You can filter which tests to run directly in the console, re-run only failed tests — it’s a beautiful setup.
However, with this great advantage comes the question of debugging.
When tests are run in Chrome via Karma, it’s easy to set a breakpoint in Chrome DevTools and debug in a familiar environment. How does this work with Jest?
There are several methods to do this:
- Common via Chrome DevTool for Node
- Built-in into the IDE via VSCode
- Built-in into the IDE via Webstorm
Conclusion
Jest is fast and great for use in CI. With thousands of tests, it runs super quickly, both on CI and locally. However, debugging front-end tests with Jest can be a bit unfamiliar. Configuration issues with TypeScript might arise, and migrating a large front-end project to Jest can be painful.
On the other hand, Karma + Jasmine have been around longer, with no tricky DOM API emulation. There are plenty of reporters, and you can debug tests visually in the browser.
Is there a clear winner? Of course not, the choice is yours! :)
Other Testing Frameworks
I know five framework names: Mocha, Tape, and Ava. Oops, only three! But these are just the well-known ones for unit testing!
How are they different from Jasmine and Jest? They are younger than Jasmine but older than Jest, with a philosophy of “lighter” solutions. In my experience, they haven’t aimed to dominate the world of large front-end apps. For Node.js backend testing, backend devs in my company use Tape and appreciate its simple syntax.
That’s why we love open source — diversity, choice, and the ability to add features ourselves!
P.S. Interesting link: Your tests aren’t slow because of Karma (or the browser)