What testing frameworks can be used for Node? The following article will share with you some Node.js testing frameworks. I hope it will be helpful to you!
Node.js quick introduction course: enter to learn
Editor's note: The author of this article is Tianzhu, a Node.js engineer at Ant Group. He will first introduce the commonly used class libraries in each part. At the end of the article, he will discuss whether unit testing is necessary. Welcome to discuss together.
mocha and jest are commonly used. The official new node test is still being polished, and the future is promising.
$mocha test/egg-view-ejs.test.js render ✓ should render with locals ✓ should render with cache ✓ should render with layout ✓ should render error renderString ✓ should renderString with data ✓ should renderString error 6 passes (398ms)
Although there are so many Runners, their output standards are all in TAP format, and the results are output through different Reporters.
Just writing a single test is not enough. We need to know whether all branch processes of the code are covered, so we usually need to use code coverage tools.
It used to be istanbuljs, but later the author rewrote nyc. They mainly bear two responsibilities: one is to translate the code to insert the piling code, and the other is to support various Reporters to generate coverage reports.
Later, V8 built-in coverage statistics
, that is, there is no need to translate the code anymore, and coverage data collection is natively supported.
Then this author wrote a c8 focused on generating coverage reports.
To verify variable results, assert is essential.
Historically: expect.js, should.js, chai and power-assert, jest also has its own built-in expect.
But now Node.js official assert/strict is actually pretty good.
Among them, power-assert is what we at EggJS have been using. I also mentioned it many years ago: "Probably the best JS Assert library - The Emperor's New Clothes".
const assert = require('power-assert'); describe('test/showcase.test.js', () => { const arr = [1, 2, 3]; it('power-assert', () => { assert(arr[1] === 10); }); }); //output: 4) test/showcase.test.js power-assert: AssertionError: # test/showcase.test.js:6 assert(arr[1] === 10) | | | | 2 false [1,2,3] [number] 10 => 10 [number] arr[1] => 2
PS: If you want to verify the file content, I have also written an assert-file, welcome to try it.
Because it is a unit test, it is often necessary to simulate the environment or downstream responses.
sinonjs is not bad and supports mocks, stubs, etc. jest also has its own mock library built in.
If it is HTTP testing, nock is very powerful and can help you mock the server response.
nock('http://www.example.com') .post('/login', 'username=pgte&password=123456') .reply(200, { id: '123ABC' })
However, the official undici request library of Node.js also has built-in Mock capabilities.
There is also a term called snapshot, which means dumping the data during operation and directly using it as mock data for the next test, which can improve the efficiency of writing tests to a certain extent.
To test HTTP Server scenarios, the supertest library is indispensable.
describe('GET /users', function() { it('responds with json', async function() { return request(app) .get('/users') .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(200) .then(response => { assert(response.body.email, '[email protected]'); }); }); });
One of the major usage scenarios of Node.js is the command line CLI, such as Webpack and Babel, which themselves also require unit testing.
This is what we recommend:
GitHub - node-modules/clet: Command Line E2E Testing
GitHub - node-modules/coffee: Test command line on Node.js
import { runner, KEYS } from 'clet';
it('should works with boilerplate', async () => { await runner() .cwd(tmpDir, { init: true }) .spawn('npm init') .stdin(/name:/, 'example') // wait for stdout, then respond .stdin(/version:/, new Array(9).fill(KEYS.ENTER)) .stdout(/"name": "example"/) // validate stdout .notStderr(/ npm ERR/) .file('package.json', { name: 'example', version: '1.0.0' }) // validate file });
For lightweight page crawling, you can directly use HTTP to request the library. Unci is recommended.
To simulate the actual execution of the browser, selenium and phantomjs were used in the early days.
Then Google officially released puppeteer. Due to the accumulation of Chromium and based on the devtools-protocol protocol, it quickly became popular and killed the first two. Similar competing products include playwright and cypress.
By the way, I am going to download macacajs, a multi-terminal testing tool. In addition to browsers, it also supports the testing of mobile APPs and desktop APPs. It is open sourced by engineers from the Yuque team.
When we write open source, we often need automated continuous integration services to help us test.
Players in this field include: Travis, Appveyor, GitHub Actions, etc.
Now I basically use GitHub Actions, and the level of integration is so cool.
There is no doubt that unit testing is very important. It is a necessary ability and professional quality of a qualified programmer.
Of course, we are not 100% coverage fanatics. In many cases, we need to pursue the balance point of ROI.
First of all, let me correct a common newcomer's point of view: Is writing unit tests a waste of time?
In fact, writing unit tests will save you time. The reason for that counter-intuitive view is that the comparison conditions are often not objective. We need to consider the cost of regression after modifying the code twice under the same quality requirements.
For a fair comparison, in addition to considering the "time to write a single test", what is easily overlooked is the "time to perform regression testing after each code modification":
When writing a single test, create various branch mocks in the early stage, and the time for regression testing is just typing on the keyboard;
Without writing a single test, you need to update the code into the application, and then manually simulate various situations to test, such as opening a browser and clicking on many different places.
How time-consuming these two are is clear at a glance.
It’s nothing more than initial investment + maintenance cost + emphasis on return quality. Each company has its own scale when making decisions after weighing them.
Of course, many of the scenarios I mentioned are framework libraries (including front-end and Node.js), server-side applications, command-line tools, etc. It is true that some front-end applications that have a large change in UI display or fast loading and unloading are For the activity page, the corresponding single test maintenance cost is indeed very high. At this time, it is reasonable to appropriately abandon the single tests of some non-core branches based on ROI.
But we must understand that this is a last resort. We can reduce the maintenance cost of unit testing through various means, but we cannot claim that unit testing is useless.
There is also a semi-automated regression test in the front-end field, which is based on diff to automate comparison and then remind the owner to pay attention to the impact of changes. This is just like the tool libraries above, which are all here to help reduce the cost of writing single tests.
This is also a wrong view. Unit tests should be written by programmers themselves , because it is your own code, and you must be responsible for it. This is a kind of professionalism. Any team with a little bit of standardization needs CI testing when submitting code, otherwise there will be no quality Code Review collaboration.
Test students are responsible for larger-level work such as integration testing, regression testing, and end-to-end testing .
The division of labor is different, so please don’t blame others.
Unit testing is very necessary. Writing unit tests is the basic professional quality of programmers. Write as much as you can. In individual scenarios, you can make choices based on ROI.