October 25, 2017
The Road to Front-End Testing
In today's world of software development, it is essential to test every aspect of the software you're building. Front-end testing has grown in prominence, so much so that it has its own set of frameworks and libraries for testing. The road to front-end testing involves making many decisions, especially around testing frameworks, tools, and libraries to use, and there are many choices to be made.
The main decisions you will have to make when embarking on the road to front-end testing include identifying:
- Which testing framework to use
- Which assertion library to use
- Which helper library to use
- Where to run our tests
Choosing a Testing Framework
There are various options to select from when choosing a testing framework. Here are a few choices, outlined:
Tests written in Mocha run serially. You can install this using NPM install or using Bower. Mocha does not come with its own assertion library, so most users choose Chai as their assertion library when working with Mocha. Mocha does not have a test double library; instead, you would most likely use Sinon as your test double library. Mocha has great support for and simplifies working with asynchronous code by making use of callbacks or even Promise. Mocha provides for all the necessary hooks like before(), after(), beforeEach(), and afterEach(). It also provides for repeating a test to retry a failed test. It also comes with a command line utility that you can use to run your tests.
Jasmine's API is very similar to Mocha. In Jasmine, test doubles are in the form of Spies (Spy is a function that replaces a specific function that you want to control in a test and record how it is used in a test). Asynchronous testing in Jasmine is also very similar to how you would do in Mocha. Jasmine does not come with its test runner, so you usually would use Karma by the Angular team as your test runner. Jasmine is hosted on GitHub (https://github.com/jasmine/jasmine).
So if you want to go with a mature framework, then you can choose from Mocha or Jasmine, and if you're going to work with React, then Jest might be a good option. On the other hand, if you feel like being adventurous you can opt for the newer frameworks Tape or AVA.
Choosing an Assertion Library
Once we've picked a testing library to use, we then have to decide on an assertion library. Outlined below are some of the more popular assertion libraries:
Expect is also an option for an assertion library that is more compact than Chai. Expect has now been taken up by Jest, so all further development is happening at Facebook/Jest. Spy is inbuilt in Expect; this is small and straightforward, and is gaining in popularity.
Choosing a Helper Library
Once you zero in on which assertion library to work with, your next challenge is which helper libraries to use for testing. The two most popular options when it comes to helper libraries are React Test Utils and Enzyme. We've broken both of them down below.
React Test Utils
React Test Utils is a library that is built by Facebook and used explicitly for testing React Components. It has a verbose API that makes it easy to test React Components. The most useful utility in React Test Utils is the ability to simulate an event dispatch on a DOM node. One of the drawbacks with this is that tests can be brittle, as it relies on the indexes of child elements.
This helper library provides two options for testing React Components:
- Using shallowRender - this renders a single component, is fast and simple, and requires no DOM.
- Using RenderIntoDocument - this will render a component along with all of its child components. It requires a DOM and supports simulating interactions.
You can learn more about React Test Utils here: https://reactjs.org/docs/test-utils.html
While Enzyme uses React Test Utils behind the scenes, it provides a much different interface and adds more methods than React Test Utils. It also uses JSDOM (In memory DOM) and Cheerio to provide fast jQuery style selectors. Enzyme exports three different modes to render and test components - shallow, mount, and render. Shallow is the recommended mode for beginners.
Using Enzyme simplifies React component testing. I would suggest going with Enzyme in this situation.
Choosing Where to Run Tests
Once we've determined all of the libraries to use, we have to decide where we want our tests to run. We've outlined three different options:
- You can run them on a browser, which is a slower option. To do this, you can use Karma, a popular test runner for running tests in real browsers.
- You can run them on a Headless Browser using PhantomJS; however, this means it is not an active project.
- You can run them in In-memory DOM, which is very fast and quick to set up. You can use Enzyme for this.
Finally, where would you place your tests? The two main options are either putting them in a central folder or spreading them out along with with the files that they test. Mocha expects your tests to be in a /test folder. Placing the files next to the files being tested makes it easier to work with and to import the files under the test.
In conclusion, there are many things to keep in mind when it comes to front-end testing. These choices are not easy because front-end frameworks and libraries are evolving so fast that it is challenging to keep track. What was on-trend yesterday is out-of-date today. So make sure you do your research before making your final choice, and be prepared to evolve and embrace changes as they come.
- Mocha: https://mochajs.org/
- Jasmine: https://jasmine.github.io/
- Jest: https://facebook.github.io/jest/
- Chai: http://chaijs.com/
- React Test Utils: https://react-cn.github.io/react/docs/test-utils.html