Why Do We Need Unit Testing?
Suppose you’re making a bowl of scrambled eggs. What will you need? Eggs, milk, cheese, vegetables, salt and maybe some bacon as well. Before cooking, you’ll check these parts of the project:
- Are the eggs fresh?
- Is the milk fresh?
- Are the utensils clean?
- Are the vegetables and bacon fresh?
- Is the frying pan heated enough?
And the list goes on and on.
You can consider the list above to be test cases for unit testing. Remember, you aren’t testing the finished product—only the individual components.
Benefits of Testing
First, the main benefit of unit testing is that it makes your project more agile. Whenever you add a new feature, you may have to change the old code. Changing a code that’s been tested already is costly and risky. However, if you run unit tests on the new code, you’ll be confident that the new code won’t break any old feature.
Not only that, unit testing helps you find bugs early in the development cycle. If you’re a developer, finding and fixing the bugs by yourself will improve the code quality and make the testing phase easier.
Finally, since you find bugs early, the bug fixing cost decreases. Just imagine: What if the testing team finds a bug during acceptance or system testing? Since the integration of the modules is already done, fixing the bugs will consume a lot of time.
As per the survey, the most used frameworks (in order from most to least popular) are:
- Testing Library
Why is Jest popular?
- It’s easy to learn.
- It requires zero setup.
- Managing large test cases is relatively easy because of a snapshot capturing feature.
Cypress is popular among testers and developers because it requires no setup. The framework runs on the browser, where it provides an interactive interface. Not only that, you can use Cypress on Mac, Linux, and Windows. Also, the test runner of Cypress allows automated screenshot and video capturing.
Generally, React developers prefer Cypress. But Cypress also supports other JS frameworks, including Angular and Node. Often, testers compare Cypress with Selenium. But the key difference between the two is that Cypress doesn’t need to integrate with your code.
Here are a few reasons this framework is popular:
- Puppeteer supports async, await, and other ES6 features.
- It supports automated testing for keyboard input, form submit, and many more features.
- Since the tests are browser specific, the tool can also set custom size and resolution of the browser. This helps in responsive testing as well.
Once upon a time, developers considered Mocha to be the best JS unit testing framework. However, Mocha’s demand is declining because of a complex setup process. Still, many companies where developers work on large projects trust Mocha. Why is that?
- You can use Mocha for the back end as well as front end testing.
- Mocha provides a clean base for writing test cases.
- This framework can mock objects to perform flexible tests.
- Mocha also supports Node JS debugger.
AVA is a great testing library for Node.js. The testing library became popular because of the process isolation it offers. This means that each test file runs in a separate Node.js process. It’s an important property to be able to trust the output of your tests. You don’t want interference to happen between the different test cases. On top of that, tests finish much faster due to their concurrent execution.
Here are some of its most favored characteristics:
- Fast execution
- Simple syntax
- Enforces writing atomic tests
- Magic assert: Easy-to-understand assertion differences
Other popular frameworks are Jasmine, Testing Library, and many more.
You may wonder, “Why did developers and testers vote Jest as the best framework?” You’ll find that out in the next section.
Why Is Jest Considered the Best?
Let’s find out why developers and testers prefer Jest.
Easy to Set Up
Installation of Jest is very simple. All you need to do is:
- Get npm or yarn on your system.
- Type this code if you’re using npm:
npm install --save-dev jest
- If you’re using yarn, type:
yarn add --dev jest
That’s it. Installation is done!
You’ve heard about Airbnb, right? Previously they used Mocha for running tests. When they switched to Jest, on a 32 core system, the runtime of test cases dropped to 4.5 minutes from 12 minutes.
Jest makes your test cases run faster by …
- Running test cases in parallel.
- Running the slowest test first. This ensures that the CPU uses all cores to the max.
One Store for Everything
When you install Jest, you’ll get spies, in-built matchers, and a huge mocking library. Since Jest is based on Jasmine, naturally, the tool got all the great features of Jasmine. Moreover, Jest supports TypeScript, which makes Angular testing easier. You can also capture snapshots and perform visual regression testing with the help of Jest.
Wouldn’t it be great if a testing tool ran automated test cases whenever you changed the code? Well, your dream comes true with Jest. The frameworks can run in watch mode. All you need to do is run this command in the command-line interface:
After that, Jest will check the app and execute testing whenever you make any changes in the code.
Test Coverage Reports
What if you test only 80% of your code? What if by mistake you’re unable to test the remaining 20%? In that case, chances are that testers may discover some critical bugs in a later stage. Jest gives you the solution by providing a built-in coverage report. All you need to do is run this command:
$ jest --coverage
The framework will provide you a test coverage report that shows what percentage of the code has been tested. You can define the output folder for this coverage report using the
$ jest --coverage --coverageDirectory='myDir'
Note that it won’t be an easy task to hit 100% code coverage. Sometimes, you’ll have to invest a lot of time to cover particular lines of code with unit tests. It’s better to opt for integration testing to verify if the logic works instead of trying to unit test these lines of code. On top of that, 100% code coverage doesn’t equal bug-free code. You can still make mistakes in the tests you write that might return false-positives.
If you care about fast unit testing, mocking is a vital feature. Mocking helps you replace dependencies that are slow. Apart from simple mock functions, Jest helps you to fully control the dependencies in several ways
- Timer Mocks: Do you want to test a code that fires after a certain time? Timer mocks of Jest helps you to test timer related functions, such as setInterval() or setTimeOut().
- ES6 Class Mocks: You can mock all the classes of Ecma 6 script with Jest’s help.
- Manual Module Mocks: Sometimes you may need to replace an entire module instead of a few functions. Jest helps you with that. Once you set a manual module, the code will target the mock, not the real module.
With Jest, you can quickly mock functions or assign a variable a mock function. First, let’s create a simple mock.
const myMockFunc = jest.fn(); console.log(myMockFunc()); // > undefined
Next, let’s define a mock value the function should return when it’s getting called. It’s even possible to chain mock values. In the below example, we want to return the boolean
false only once and then always return
const myMockFunc = jest.fn(); console.log(myMockFunc()); // > undefined myMock.mockReturnValueOnce(false).mockReturnValue(true); console.log(myMock(), myMock(), myMock()); // > false, true, true
It’s as easy as that!
Deploy a Bug-Free Web Application With Unit Testing
This post was written by Arnab Roy Chowdhury. Arnab is a UI developer by profession and a blogging enthusiast. He has strong expertise in the latest UI/UX trends, project methodologies, testing, and scripting.