Implement unit tests in Nodejs

Source: Internet
Author: User

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
    1. Test framework
    2. Assertion Library
    3. Changes in requirements
    4. Asynchronous test
    5. Anomaly Testing
    6. Testing Private methods
    7. Test your web App
    8. Coverage
    9. Use Makefile to String tests together
    10. Continuous integration, TRAVIS-CLI
    11. Some views
    12. Eggs
    13. 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:

    • Should.js
    • Expect.js
    • Chai
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
    1. Test Framework Mocha
    2. Assertion Library: Should.js, Expect.js, Chai
    3. Coverage: Istanbul, Jscover, blanket
    4. Mock library: Muk
    5. Test Private Method: Rewire
    6. Web test: SuperTest
    7. 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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.