- 1. JavaScript testing #1. Explaining types of tests. Basics of unit testing with Jest
- 2. JavaScript testing #2. Introducing Enzyme and testing React components
- 3. JavaScript testing #3. Testing props, the mount function and snapshot tests.
- 4. JavaScript testing #4. Mocking API calls and simulating React components interactions
- 5. JavaScript testing #5. Testing hooks with react-hooks-testing-library and Redux
- 6. JavaScript testing #6. Introduction to End-to-End testing with Cypress
- 7. JavaScript testing #7. Diving deeper into commands and selectors in Cypress
- 8. JavaScript testing #8. Integrating Cypress with Cucumber and Gherkin
- 9. JavaScript testing #9. Replacing Enzyme with React Testing Library
- 10. JavaScript testing #10. Advanced mocking with Jest and React Testing Library
- 11. JavaScript testing #11. Spying on functions. Pitfalls of not resetting Jest mocks
- 12. JavaScript testing #12. Testing downloaded files and file inputs with Cypress
- 13. JavaScript testing #13. Mocking a REST API with the Mock Service Worker
- 14. JavaScript testing #14. Mocking WebSockets using the mock-socket library
Hello! Today we start another big series, which is about JavaScript testing. There are various different types of tests and we will start by explaining some of them. In the beginning, we will cover the basics of unit testing, which is testing individual parts of our application and checking if they are fit to use. To do this we will use Jest, a testing framework developed by Facebook. It is ready to go and equipped with features that you will need to do your testing. Let’s go!
Testing javascript tutorial – types of tests.
A test is a code that checks your code. Tests might make you feel more confident about your application. They will also prevent you from fixing the one thing while breaking another. You can test many aspects of your application, from a single function and its return value to a complex app running in the browser. Since this is the first article of the course, we will briefly compare popular types of testing.
Unit tests
Unit tests cover blocks of code to ensure they run without problems. A tested unit can be a function, a module, a class. Unit tests should be isolated and independent of each other. For a given input, unit test checks the result. It can help you make sure that individual parts of your applications work as expected by finding problems early and avoiding regressions.
Integration tests
Even if all your unit test pass, it still just means that the parts are working well on their own. Still, the application might fail. Integration tests cover cross-module processes, where individual modules are combined and tested while working together. Thanks to them you can provide a way to ensure that your code works well as a whole.
End to end tests (E2E)
As opposed to other types of tests, E2E tests are always run inside a browser (or a browser-like) environment. It might be an actual browser that opens and the tests are run inside. It also may be a headless browser environment, which is a browser running without the user interface. The point of E2E tests is emulating an actual user within our running application. They will simulate behavior like scrolling, clicking, and typing and check if our application works well from the point of view of an actual user.
Unit tests with Jest
Jest is a testing framework developed by Facebook. One of its goals is to provide a “zero-configuration” experience with tools ready to use out of the box. It’s been around for a while and it’s fast and reliable. Let’s use it!
1 |
npm install --save-dev jest |
Remember to add it to the npm scripts too.
package.json
1 2 3 |
"scripts": { "test": "jest" } |
For the sake of simplicity I will use Jest here with simple, pure Node.js modules (no webpack included). Later we will learn how to use Jest with React
First, let’s create some simple function that we could test.
divide.js
1 2 3 4 |
function divide(a, b) { return a / b; } module.exports = divide; |
Jest uses a regular expression to determine which files are tests. By default it will execute .js and .jsx files if they are in the __tests__ directory, or end with .test or .spec suffix. You can specify it in the package.json file of your project with the testRegex property.
package.json
1 2 3 |
"jest": { "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$" } |
If you would like to know more about Regex and how to use it in JavaScript, check out my Regex course
Finally, let’s create the test file. To follow a default naming configuration, we will call it divide.test.js.
divide.test.js
1 2 3 4 5 |
const divide = require('./divide'); test('dividing 6 by 3 equals 2', () => { expect(divide(6, 3)).toBe(2); }); |
Running this test with npm run test will result in:
1 2 |
PASS ./divide.test.js ✓ dividing 6 by 3 equals 2 (5ms) |
The test function runs a test. It takes three arguments: the name of the test, the function containing the expectations and a timeout (in milliseconds). The timeout defaults to 5 seconds and specifies how long to wait before aborting the test if it takes too long.
The expect function is used to test a value. As an argument it takes a value that you want to test: in our example, it is the return of the divide function. You can call a set of matcher functions (like toBe used in the example) to test the value in a certain way. For a full list visit Jest documentation.
Grouping tests
There will usually be more than one test per file. With Jest, you can group them with the describe function. It creates a block that can combine several tests. To better visualize it, let’s run some tests on the global Math object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
describe('in the math global object', () => { describe('the random function', () => { it('should return a number', () => { expect(typeof Math.random()).toEqual('number'); }) it('should return a number between 0 and 1', () => { const randomNumber = Math.random(); expect(randomNumber).toBeGreaterThanOrEqual(0); expect(randomNumber).toBeLessThan(1); }) }); describe('the round function', () => { it('should return a rounded value of 4.5 being 5', () => { expect(Math.round(4.5)).toBe(5); }) }); }) |
You may notice the usage of the it function instead of the test function. It is a commonly used alias. Running it === test returns true.
Grouping your tests like that make your code cleaner. You should care for the quality of both the code of your application and the code that tests it.
Aside from making your code more readable it also helps in providing better error messages, if something goes wrong. If you would change the tests to contain expect(typeof Math.random()).toEqual('string'), you would get such a message:
1 2 3 4 5 6 7 8 9 |
FAIL ./math.test.js ● in the math global object › the random function › should return a number expect(received).toEqual(expected) Expected value to equal: "string" Received: "number" |
Summary
Today, as an introduction, we’ve explained what the most basic types of JavaScript tests are. The first type of tests that we’ve covered are the unit tests. To perform them, we’ve learned the very basics of the Jest framework. It included the knowledge on how to run tests (installation and file naming). To run tests we’ve used the test, it, and the describe functions. A lot more on that topic is soon to come, so stay tuned!
Excellent article and descriptive man! I also have an article about testing. Check it out and give me your opinion.
https://medium.com/yazanaabed/what-i-know-about-testing-in-javascript-6657d2188c3a
Thank you very much, excellent documentation. How can I do testing to sockets?
I think it would be very good for the serie.