Recently, I published a post titled You Should Be Writing Tests where I lightly discuss some of the important reasons for testing on the front-end.
After speaking with some people who reached out to me, it became clear to me that people want to test on the front-end, but some developers legitimately do not know the best way to do so.
And honestly, when you look at the front-end testing landscape, it is confusing AF as the cool kids say (or so I am told). Where do you even begin? What is a Jest? Is Mocha a coffee or something related to testing? Jasmine, that's the nice smelling stuff, isn't it?
I do not delve into end-to-end testing in this article. For that, I highly recommend Cypress for end-to-end testing (it only currently supports Chrome). If you want to run e2e tests in multiple browsers, then Protractor is a safe choice (just older and configuration heavy).
When it comes to test runners you have really two solid options for running unit tests:
Created by Facebook, Jest runs your tests in a non-browser environment. As such, it can introduce complexities when you're testing code that is using dependencies that touch the DOM or use other libraries like jQuery.
This seems to be one of the most popular options right now, and honestly, I enjoy using Jest. It's fast and Facebook does a great job maintaining it. But, you can't run tests in a real browser like Chrome or Firefox.
The upside of tests not being run in a real browser is that it is really fast. It takes just a few seconds to run 322 tests in a project I am currently working on, it would probably take a good couple of minutes running the same tests in Karma, at least one minute.
To work around the lack of real DOM, you can patch the needed features either yourself or downloading a community created plugin. Numerous libraries have their own mocks/overrides already, including support for API's such as fetch and working with dates. For libraries like Lodash, you can mock them on a needed basis.
Another reason I love Jest is that you do not need to install any testing framework like Jasmine or Mocha. Install Jest and then start writing tests, using familiar Jasmine like syntax.
And yet another reason to love Jest, it plays nicely with TypeScript without needing to do anything fancy to support it. No additional plugins or anything else required.
If you have been around for a while, especially if you have worked with AngularJS (the original Angular) then there is a good chance you have used Karma. Unlike Jest, your tests are run in real web browsers.
Karma plays nicely with front-end code. It works with any code that already currently runs in a web browser. One of its downsides is that it is configuration heavy and tests can take a lot longer to run.
Speaking from experience, Karma is starting to show its age. It has great support for different testing environments and services like Sauce Labs, but I have had to really hack my
karma.conf.js file to get it working in large applications.
Also, unlike Jest, getting TypeScript to work in Karma involves using a plugin and configuring Karma to transpile your TS files before it runs them.
If you don't need to test in a real browser, choose Jest. If you want to test in a real browser, choose Karma.
A testing framework is a way in which you write your tests, it comes with numerous methods for checking values inside of your tests (known as assertions). Once again, you really have two popular options you'll encounter a lot.
In Jasmine you get a powerful assertion library, as well as support for all of the basics like async/, await and more. It's a battle-tested testing framework that has been around for a very long time.
Unlike Jasmine, Mocha doesn't aim to be an all-in-one batteries included solution. It comes with no assertion library, but the most commonly used one with Mocha is Chai (which supports numerous styles including Jasmine-style syntax).
Once again, unlike Jasmine, Mocha also does not come with support for test doubles (the ability to spy and mock methods and values in a test). If you work with a framework that leverages dependency injection like Angular or Aurelia, you want support for test doubles. The most commonly used option here is a library called Sinon.js.
Really, you cannot go wrong with either Jasmine or Mocha. Whenever I have used Karma, my preferred testing framework is Jasmine because I am lazy and hate having to manage dependencies and configure them. It doesn't mean Jasmine is the better option, but it is the easiest one.