In teamwork, you write a function for your teammates to use, run to your teammates and say, you pass a value in, he will return B results. After a while, your teammates ran over and said, "I passed a value and returned to the C result, what's going on?" Have you ever tested it?
We write a project together, inevitably there will be a function I want to write to rely on other people's functions, but the value of this function is not trustworthy? Unit testing is an important criterion for measuring code quality, and throughout GitHub's popular projects, there are test folders and Buliding-pass. If you have contributed modules to the community and want to use them more, add unit tests and let your module be trusted by others.
To write unit tests in Nodejs, you need to know what test framework to use, how to test asynchronous functions, how to test private methods, how to simulate a test environment, how to test Web applications that rely on HTTP protocols, to understand TDD and BDD, and to provide coverage for testing.
Directory
- Test framework
- Assertion Library
- Changes in requirements
- Asynchronous test
- Anomaly Testing
- Testing Private methods
- Test your web App
- Coverage
- Use Makefile to String tests together
- Continuous integration, TRAVIS-CLI
- Some views
- Eggs
- Finishing
Test framework
Nodejs's test framework is also used to say? Everybody's using it, Mocha.
Mocha is a feature-rich JavaScript testing framework that can run in node. js and in the browser, supporting BDD,TDD,qunit,exports - The main examples in this article are BDD using a closer and thought-out approach, if you know more about the official website of Mocha
Test interface
Mocha's BDD interfaces are:
describe()
it()
before()
after()
beforeEach()
afterEach()
Installation
npm install mocha -g
Write a stable and reliable module
The module has the Limit method, enter a value, less than 0 when the return 0, the rest of the normal return
function (num) { if (num < 0) { return 0; } return num;};
Directory Assignment
lib, where the module code is stored
testWhere the unit test code is stored
index.js, the place to export the module outward
package.json, Package description File
Test
var lib = require (' index ');d escribe (function () { describe (function () { It (function () { lib.limit ();});}) ;
Results
Execute in current directory mocha :
$ mocha ? 1 Test Complete (2ms)
Assertion Library
The above code just runs the code, and does not check the results, it is necessary to use the assertion Library, node. JS is commonly used in the assertion library:
Plus assertions
Using should libraries to add assertions to test cases
function () { lib.limit (Ten). Should.be.equal ();});
Changes in requirements
Requirements Change: limit This method also requires that the return value is greater than 100 to return 100.
It is the value of the test case to refactor the code for the requirements,
It ensures that your changes do not cause damage to the original results.
However, some of the more work you have to do is to write new test code for the new requirements.
Asynchronous test Test Async callback
New Async function in Lib library:
function (callback) { setTimeout(function () { callback (); (Ten);};
To test asynchronous code:
function () { It (function ) { lib.async (function (result) {done (); }); });});
Test Promise
Use the Promise assertion interface provided by should:
finally|eventually
fulfilled
fulfilledWith
rejected
rejectedWith
then
Test code
Describe (' should ',function() {Describe (' #Promise ',function() {It (' Should.reject ',function () { (NewPromise (function(Resolve, Reject) {Reject (NewError (' wrong ')); }). Should.be.rejectedWith (' Wrong '); }); It (' Should.fulfilled ',function () { (NewPromise (function(Resolve, Reject) {Resolve ({username:' JC ', age:18, Gender: ' Male '})). should.be.fulfilled (). Then (function(IT) {It.should.have.property (' username ', ' JC '); }) }); });});Timeout support for asynchronous methods
The default timeout setting for Mocha is 2s, and a timeout error will be reported if the test executed exceeds 2s.
You can proactively modify the time-out period in two ways.
Command-line
mocha -t 10000
API type
function () { this. Timeout (10000); It (function ) { Lib.async (function (result) {done (); }); }) ;});
In this case async , the execution time does not exceed 10s, it will not error timeout errors.
Anomaly Testing
The exception should be how to test, there is now a getContent method, he will read the contents of the specified file, but does not necessarily succeed, will throw an exception.
function (filename, callback) { ' utf-8 ', callback);};
It's time to simulate (mock) the wrong environment.
Simple mock
Describe ("GetContent",function () { var_readfile; Before (function() {_readfile=Fs.readfile; Fs.readfile=function(filename, encoding, callback) {Process.nexttick (function() {Callback (NewError ("Mock ReadFile Error")); }); }; }); //it ();Afterfunction () { //Remember to restore when you're done with it. Otherwise affect other caseFs.readfile =_readfile; })});Mock Library
Mock mini-module: a muk slightly graceful notation:
var fs = require (' FS '); var muk = require (' Muk '); before (function () { function(path, Encoding, callback) { Process.nexttick (function () { callback (new Error ("Mock readFile Error")); }); // it (); After (function () { muk.restore ();});
Testing Private methods
For some internal methods, not exposed through exports, how to test it?
function _adding (NUM1, num2) { return num1 + num2;}
Export method by Rewire
Module:rewire
function () { var lib = rewire ('.. /lib/index.js '); var litmit = lib.__get__ (' limit '); Litmit (ten);});
Test your web App
When developing a Web project, test an API, such as: /user how do you write test cases?
Use:supertest
varExpress = Require ("Express");varRequest = require ("SuperTest");varApp =Express ();//Defining RoutesApp.get ('/user ',function(req, res) {Res.send ($, {name: ' JERRYC ' });}); Describe (' Get/user ',function() {It (' Respond with JSON ',function(done) {request (APP). Get ('/user '). Set (' Accept ', ' Application/json '). Expect (' Content-type ',/json/). Expect (200). End (function(Err, res) {if(Err) {done (err); } RES.BODY.NAME.SHOULD.BE.EQL (' Jerryc '); Done (); }) });});Coverage
When testing, we often care if all the code is tested.
This indicator is called code coverage. It has four dimensions of measurement.
- Line Coverage : Is every line executed?
- function Coverage : Does each function call?
- Branch coverage (branch coverage): is every if code block executed?
- Statement Coverage (statement coverage): are each statement executed?
Istanbul is a code coverage tool for JavaScript programs.
Installation
$ npm install -g istanbul
Coverage testing
After you have written the above test cases, execute the command:
istanbul cover _mocha
will be able to get coverage:
jerryc% Istanbul cover _mocha module limit should success async ? Async GetContent ? getcontent Add should #Promise ? should.reject ? should Fulfilled 6 passing (32ms)================== Coverage Summary ====================== Statements 100% (10/10) Branches : 100% (2/2) Functions : 100% (5/5) Lines : 100% (10/10) = = ========================================================
This command also generates a coverage subdirectory where the Coverage.json file contains the raw data for coverage, and Coverage/lcov-report is a coverage report that can be opened in the browser, with detailed information on exactly what code is not covered.
In the above command, istanbul cover the command followed by the _mocha command, the preceding underscore cannot be omitted.
Because Mocha and _mocha are two different commands, the former creates a new process to perform the test, and the latter executes the test in the current process (that is, the process where the Istanbul resides), so that the Istanbul catches the coverage data. The same is true for other test frameworks, where tests must be performed in the same process.
If you want to pass in a parameter to mocha, you can write it like this.
$ istanbul cover _mocha -- tests/test.sqrt.js -R spec
In the above command, the section behind the two conjunctions is passed as a parameter to the Mocha. If you do not add the two conjunction lines, they will be treated as Istanbul parameters (refer to link).
Using makefile to string up items
TESTS = Test/*. test.jsreporter = Spectimeout = 10000JSCOVERAGE =./node_modules/jscover/bin/jscovertest:< c4/> @NODE_ENV =test/node_modules/mocha/bin/mocha-r $ (REPORTER)-T $ (TIMEOUT) $ (TESTS) Test-cov:lib-cov @LIB_COV =1 $ (make) test Reporter=dot @LIB_COV =1 $ (make) test Reporter=html-cov > Coverage.htmllib-cov: @rm-rf. Lib-cov @$ (jscoverage) Lib Lib-cov. Phony:test test-cov lib-covmake testmake Test-cov
Avoid version conflicts and confusion with the jscover and Mocha of the project itself
Continuous integration, TRAVIS-CLI
- Travis-ci
- Bind GitHub Account
- Open the Services hook in the admin of GitHub Warehouse
- Open Travis
- Each push will trigger the execution of the
npm test command
Note: Travis will treat an item that is not described as a ruby project. So you need to add files to the root directory .travis.yml . The contents are as follows:
Language:node_jsnode_js: -"0.12"
TRAVIS-CLI will also issue labels to the project,
Or
If the project passes all tests, it will be build-passing,
If the project does not pass all tests, it will build-failing
Some views
When implementing unit tests, it is difficult to master the "degree" of testing without a detailed specification that has been proven in practice, too small to be applied, too large to violate the "others" site. God's God, Caesar's return to Caesar, to unit test the magic spell is not necessarily a bad thing, but more conducive to the power of unit testing, code refactoring and improve code quality to provide power.
This document, from Geotechnical, is a very rare rule of thumb. You can use this code as a template, combining the experience of your team, to sort out an internal unit testing guideline.
Unit Test Guidelines
Eggs
Finally, a library is introduced:faker
He is a library that can forge user data, including attributes that users often include: personal information, Avatar, address, and so on.
is a very good library for simulating user data in the early stages of development.
Support for node. JS and browser side.
Organize the NODEJS Unit test tool
- Test Framework Mocha
- Assertion Library: Should.js, Expect.js, Chai
- Coverage: Istanbul, Jscover, blanket
- Mock library: Muk
- Test Private Method: Rewire
- Web test: SuperTest
- Continuous Integration: TRAVIS-CLI
Reference
- Https://github.com/JacksonTian/unittesting
- Http://html5ify.com/unittesting/slides/index.html
- Http://www.ruanyifeng.com/blog/2015/06/istanbul.html
- Http://coolshell.cn/articles/8209.html
- Http://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests
- Https://github.com/yangyubo/zh-unit-testing-guidelines
- Http://www.codedata.com.tw/java/unit-test-the-way-changes-my-programming
- Http://wiki.ubuntu.org.cn/%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:MakeFile%E4%BB%8B%E7%BB%8D
- Https://github.com/yangyubo/zh-unit-testing-guidelines
- Https://github.com/visionmedia/superagent/blob/master/Makefile
- Cnode Blog: https://cnodejs.org/topic/55b9e875f36f579657fc52f3
Implement unit tests in Nodejs