DEV Community

Nicholas Bilyk
Nicholas Bilyk

Posted on

Which Test Framework?

I'm going to keep this short, sweet, and very opinionated. I recommend you do your own research but for those looking into testing JavaScript or TypeScript I hope to help with a very high level overview. Also a disclaimer that this is the web, check the dates on your sources, this article might be obsolete tomorrow :)

So you're choosing a testing framework, which to choose? What are the kids using these days?

(Ranked by popularity, not by my personal preference)

#1 Jest

Creator: Facebook
Weekly Downloads: 13,942,759

Pros:
Most popular
Good tooling / plugins for IDEA, VSCode, CLI

Cons:
NodeJS only, if you want to run Jest in a browser it takes considerable effort with puppeteer. Jest-puppeteer is poorly maintained.

Overall:
Jest is great for unit tests. My staunch opinion is that code written for a browser should be integration tested in a browser. This is at the very least more difficult to do in Jest than Mocha or Jasmine, so this is a non-starter for me.

Jest has batteries included, that means it is full-featured in that you get a test runner, assertion libraries, and many utilities like mocking, spies, time harnesses, asynchronous testing, you name it.

#2 Mocha

Creator: OpenJS Foundation
Weekly Downloads: 5,293,954

Pros:
Works well with Node and browsers
Has good tooling for IDEA, VSCode, and CLI

Cons:
Requires additional libraries for everything. Typically chai for assertions, sinon for mocking.
Chai syntax is obscure and hard to remember.

Overall:
If you want to get started with mocha, you'll need a combination of libraries, for example npm i -D mocha chai sinon chai-sinon
Besides a more complicated setup, Mocha, or more specifically Chai, in my opinion, takes behavior driven development a little too far. When building your assertions in Chai there is this chaining syntax that's meant to be a human language to your tests. For example instead of: expect(undefined).toBeUndefined() it's expect(undefined).to.be.undefined
or instead of expect(foo).toEqual(bar) it's expect(foo).to.deep.equal(bar)

This can lead to easily made mistakes in your tests. expect(foo).to.be.defined will always pass because defined doesn't exist. Instead you should have written expect(foo).to.not.be.undefined, which IMHO is insane.

#3 Jasmine

Creator: Pivotal Labs
Weekly Downloads: 1,865,652

Pros:
Very similar to Jest
Batteries included
Works out of the box in Node and a browser

Cons:
Not quite Jest
Ugh, what is that color, cannon pink?
IDEA extension needs work

Overall:
This framework feels like it's trying to be Jest; the syntax is almost identical, and except for a couple nitpicks, Jasmine is succeeding. Being able to run in a browser out of the box is the real selling point here. I can create selenium tests that execute my Jasmine unit and integration tests in a headless browser for continuous integration, and I can create a static page that can run my tests on any device with a browser.
The IDEA extension needs to add debug support, debugging unit tests is a must-have for me and the only way to currently do this with Jasmine tests is to debug the main npm run test task.


TypeScript Notes:
They all work with TypeScript, but with some additional work. Namely, you have to register something like ts-node to transpile at runtime.
Example:
npm i -D ts-node

In your run configuration template:
Node options: -r ts-node/register

Jest with React has a project creator that can set things up for you out of the box. This is great if you're using React :)


Bottom Line

You do you, mang.

I'd use Jest if it had browser support (Puppeteer doesn't really cut it for me.) Maybe there's a better way, let me know :). Until then, Jasmine has been great!

Discussion (0)