Why Use Unit Testing ?
Unit testing is automated testing that focuses on a single ‘unit’ of your code, such as a function or a module. This makes the tests quick to write and to run, and therefore there can be many tests. Unit tests are specific to such a small piece of your code that it makes tracing errors easy and efficient.
The terms TDD (test-driven development) and BDD (behavior-driven development) refer to approaches to writing tests for a piece of software, and often TDD results in writing unit tests. In TDD, developers write a failing test for what they want their code to achieve first, and then write some code to pass the test. For example, if you want to write a method that gets the average of an array of integers, in TDD you would first write a unit test that fails. You would then adjust the method that is supposed to achieve this until it passes the test. In order to establish more boundaries for this method, more unit tests are written to fail, and then the method adjusted to pass them. This means that writing unit test is part of the process of test driven development.
Additionally, unit testing prevents code from becoming too fragile. Unit tests that verify a module’s functionality should still be applicable when that module has additions or changes. If a new method is added to a class and breaks existing functionality in the class, the existing unit tests will fail. This will indicate to the developer that either the new method has negative side effects, or that the scope of the change is larger than just that method and the existing unit tests need to change. Either way, the developer knows before deployment that their addition or modification breaks existing expected functionality.
Unit testing also provides a sort of make shift documentation for developers. By reading the unit tests for existing modules, a developer can establish what the functionality currently is and should be before making changes or tracking down a bug. This can help establish whether a bug is actually a bug or just missing functionality, and determine the complexity of potential updates to functionality.
First run :
to initialize a new npm package and create a package.json file. You can learn more about npm init by reading the documentation, but for the sake of this blog just know that it will create a package.json file where we will store dependencies.
npm install --save-dev jest
Note the flag:
This updates the devDependencies in your package, which are used only for local testing and development.
A Very Basic Test
To create our first basic test, we can follow the below steps. These steps mimic the basic documentation from the Jest getting-started page with some slight differences.
- Create a file named product.js and add the below code
2. Create a file named product.test.js with the below code
3. In the package.json file, change the value for “scripts” > “test” from:
"test": "echo \"Error: no test specified\" && exit 1"
Your package.json file will look like this:
4. Open your terminal and run:
npm run test
If the code matches, you should expect to see a success message that looks like this:
If you were to purposely make the test fail, by let’s say switching the multiplication sign for an addition sign in the product function in the product.js file, you would see this message:
Jest is specific here, and tells us exactly what the output should have been with Expected: 12, and what the output actually was, Received: 7. This explanation of the test’s failure can help us debug what went wrong and how to fix it.
and import and use the Example module in a test file like so:
To dive deeper into the above test, the function .toBe() is what is called a ‘matcher’ in Jest. This tests value for exact equality, hence our test that matches 30 divided by 5 to equal 6 exactly. The expect() function returns an ‘expectation’ object which we then call the .toBe() matcher on.
Here is a list of some common matchers in Jest and what they test:
- toEqual() => recursively check every field of an object or array
- toBeNull() => matches null only
- toBeTruthy() => match anything treated as true in an if statement
- toBeFalsy() => match anything treated as false in an if statement
- toBeCloseTo() => to test floating point equality
- toBeGreaterThan() => expectation is greater than
- toBeLessThanOrEqual To() => expectation is less than or equal to
- toMatch() => match strings against a regular expressions
- toContain() => check if array or iterable contains particular item
- toThrow() => check if function throws specific error
Then in our example.test.js file we can write two new tests that test the returns of these asynchronous functions:
In the above example, expect.assertions(1) verifies that a certain number of assertions are called, otherwise the test would not fail.
npm-init | npm Docs
npm init can be used to set up a new or existing npm package. initializer in this case is an npm package named create…
Community repos for Jest related projects. Jest Community has 18 repositories available. Follow their code on GitHub.
Globals · Jest
In your test files, Jest puts each of these methods and objects into the global environment. You don't have to require…