1 introduction
1.1 What is Jest?
Jest is an open source JavaScript unit testing tool released by Facebook based on the Jasmine framework. It includes built-in DOM API support for Testing environments, assertion libraries, Mock libraries, and features like Snapshot Testing and Instant Feedback. It automatically integrates assertions, JSDom, coverage reporting, and all the testing tools developers need, and is a testing framework with almost zero configuration. And it’s very friendly for testing React, also Facebook’s open source front-end framework.
1.2 Who is using it?
1.3 selling point
- Jest is a testing framework produced by Facebook. Compared with other testing frameworks, one of the major features is that it has built-in common testing tools, such as built-in assertion and test coverage tools, which are implemented out of the box.
- As a front-end testing framework, Jest can use its unique snapshot testing function to automatically test common frameworks such as React by comparing the snapshot files generated by UI code.
- In addition, Jest’s test cases are executed in parallel and only the tests for the changed files are executed, increasing testing speed. At present, the number of its stars on Github has exceeded 10,000; In addition to Facebook, other companies in the industry are starting to turn to Jest from other testing frameworks, such as Airbnb, and we believe that Jest will continue to grow rapidly in the future.
2. Prepare before class
2.1 Test Framework
The purpose of a testing framework is to provide some convenient syntax for describing test cases and grouping them. Testing frameworks fall into two categories: I understand that the differences between TDD (test Driven development) and BDD (behavior driven Development) are mainly grammatical differences, where BDD provides a more readable use case syntax, See The Difference Between TDD and BDD – Josh Davis for details. Common testing frameworks are Jasmine, Mocha, and Jest, which I’ll cover in this article.
2.2 assertions library
The assertion library mainly provides semantic methods for making various judgments about the values being tested. These semantic methods return the results of the test, either success or failure. Common assertion libraries are should.js, Chai. Js, etc.
Test coverage tool
Use it to count the test cases against the code and generate a report such as Istanbul
3 to fit
Initialize a project
mkidr $CODE_PATH && cd $CODE_PATH
npm init -y
npm i -D jest
Copy the code
⚠️ jest does not support ES6 by default. Install NPM I -d babel-jest babel-core babel-env and preset is increased.
{
"presets": ["env"]}Copy the code
Add the test script in package.json
{
"scripts": {
"test": "jest"."test:watch": "jest --watchAll"}}Copy the code
So our ingredients are ready ✌️
3.1 First example 🌰 1+2 = 3 Let’s start by writing an example function that adds two numbers. First, create the sum.js sum.test.js file
touch sum.js sum.test.js
code .
Copy the code
::sum.js::
export default function sum(a, b) {
return a + b
}
Copy the code
::sum.test.js::
import sum from './sum'
test('adds 1 + 2 to equal 3', () => {
expect(sum(1.2)).toBe(3)})Copy the code
⚠️ Jest executes all **.test.js or *.spec.js files in the current directory to complete the test, whether Jest is run globally or through NPM test. Run NPM run test
The above is a small example from the official website
3.2 New Attempts
🤔 you can modify the function sum to try the error result ::sum.js::
export default function sum(a, b) {
return a + b + 1
}
Copy the code
Run NPM run test
Requirements analysis ➡️ write unit tests ➡️ write code ➡️ Unit tests all pass so does that mean unit tests all pass without bugs? That’s not true.
So why write unit tests? As shown in the
The importance of writing unit tests
Several commonly used Jest assertions
Next, write a collection of functions ::functions.js:: and :functions.test.js:: to demonstrate some common testing methods
touch functions.js functions.test.js
Copy the code
::functions.js::
export default {
add: (num1, num2) = > num1 + num2,
}
Copy the code
::functions.test.js::
import functions from './functions'
const { add } = functions
// toBe
test('Adds 2 + 2 to equal 4', () => {
expect(add(2.2)).toBe(4)})Copy the code
4.1 not
Add tests in ::functions.test.js::
.// not
test('Adds 2 + 2 to NOT equal 5', () => {
expect(functions.add(2.2)).not.toBe(5); }); .Copy the code
The.not modifier allows you to test for situations where the result is not equal to a value, which is almost identical to English syntax and easy to understand.
4.2 toBeNull
::functions.js::
export default {
add: (num1, num2) = > num1 + num2,
isNull: (a)= > null
}
Copy the code
Add tests in ::functions.test.js::
// toBeNull
test('Should be null', () => {
expect(isNull()).toBeNull();
});
Copy the code
The test pass
4.3 toBeFalsy
ToBeFalsy determines whether the value is false
// toBeFalsy
test('Should be falsy', () => {
expect(undefined).toBeFalsy()
})
Copy the code
4.4 toBeFalsy/toBe
// functions.js
createUser: (a)= > {
const user = { firstName: 'Brad' };
user['lastName'] = 'Traversy';
return user;
}
// functions.test.js
test('User should be Brad Traversy object', () => {
expect(createUser()).toEqual({
firstName: 'Brad'.lastName: 'Traversy'
});
});
Copy the code
⚠️. ToEqual matcher recursively checks whether all attributes and their values are equal, so use the. ToEqual matcher instead of. ToBe when comparing application types.
4.5 More
Jest uses a style of assertion not too different from that of the community.
// Compare values
expect(8).toBeGreaterThan(7)
expect(7).toBeGreaterThanOrEqual(7)
expect(6).toBeLessThan(7)
expect(6).toBeLessThanOrEqual(6)
// Regex matches
expect('team').not.toMatch(/I/i)
// Arrays
expect(['john'.'karen'.'admin']).toContain('admin');
Copy the code
For more assertions, see: Expect · Jest
4.6 Testing Asynchrony
JSONPlaceholder is a free online REST API that can be used to test web requests and request parameters during development. Or when our program needs to get some fake data, fake pictures can also use it.
// functions.js
fetchUser: (a)= >
axios
.get('https://jsonplaceholder.typicode.com/users/1')
.then(res= > res.data)
// functions.test.js
// Async Await
test('User fetched name should be Leanne Graham'.async () => {
expect.assertions(1)
const data = await functions.fetchUser()
expect(data.name).toEqual('Leanne Graham')})Copy the code
Above we called expect. Assertions (1), which ensure that in an asynchronous test case an assertion is executed in the callback function. This is useful when testing asynchronous code. Doc. Ebichu. Cc/jest/docs/z… Specific documentation.
5 of actual combat
5.1 chunkArray
Write a function ::chunkArray:: splits an array into size blocks and assembles these blocks into a new array. If the array cannot be split into all equal length blocks, the last remaining elements form a block. For example:
- Example 1: Array
,2,3,4,5,6,7,8,9,10 [1]
Split size is 2, then the final output is[[1, 2], [3, 4], [5, 6], [7, 8], [9]]
- Example 2: Arrays
,2,3,4,5,6,7 [1]
Split size is 3, then the output is[[1, 2, 3], [4 and 6], [7]
This is the analysis process, which is the requirement description in our daily development. Now we convert the requirement into a single test :: chunkarray.test.js ::
// Verify that chunkArray has been declared defined
test('chunkArray function exists', () => {
expect(chunkArray).toBeDefined()
})
// Verify example 1
test('Chunk an array of 10 values with length of 2', () = > {const numbers = [1.2.3.4.5.6.7.8.9.10];
const len = 2;
const chunkedArr = chunkArray(numbers, len);
expect(chunkedArr).toEqual([[1.2], [3.4], [5.6], [7.8], [9.10]]);
});
// Verify example 2
test('Chunk an array of 10 values with length of 2', () = > {const numbers = [1.2.3.4.5.6.7]
const len = 3
const chunkedArr = chunkArray(numbers, len)
expect(chunkedArr).toEqual([[1.2.3], [4.5.6], [7])})Copy the code
ChunkArray :: chunkarray.js :: chunkarray.js ::
const chunkArray = (arr, len) = > {
// Init chunked arr
const chunkedArr = []
// Loop through arr
arr.forEach(val= > {
// Get last element
const last = chunkedArr[chunkedArr.length - 1]
// Check if last and if last length is equal to the chunk len
if(! last || last.length === len) { chunkedArr.push([val]) }else {
last.push(val)
}
})
return chunkedArr
}
Copy the code
As shown above, this is the development process, and this gameplay is also shown in some algorithmic brush communities, such as CodeWars
🤔 I am thinking about the significance of unit testing. The summary is as follows:
- Writing a single test is to sort out the requirements, before starting to write code, so that their understanding of the requirements is more clear.
- Mono testing is like a robot checking the correctness of your modules. As the project gets more complex and larger, mono testing lets developers know in advance the impact of changes and changes to modules.
6 Test Coverage
Jest comes with a built-in test coverage tool Istanbul, which adds configuration to ::package.json::
"collectCoverage": true,
"coverageReporters": ["json", "html", "text"]
Copy the code
NPM run test displays test coverage on the command line,
coverage
X. References
- Testing JavaScript with Jest (Getting Started)
- The Difference Between TDD and BDD – Josh Davis
- Front-end testing framework Jest
- No single tests, No coding – The Importance of writing unit Tests -HollisChuang’s Blog
- Jest Crash Course – Unit Testing in JavaScript – YouTube