diff --git a/Testing.md b/Testing.md new file mode 100644 index 0000000..7a9ce55 --- /dev/null +++ b/Testing.md @@ -0,0 +1,165 @@ +# Test components +### npm packages +Node-RED uses the following packages for testing. +- mocha +- should +- sinon +- supertest +- istanbul + +### Test directory structure +There are test scripts under test directory (https://github.com/node-red/node-red/tree/master/test). +Test scripts in `test/nodes` and `test/red` are located in the same hierarchy as the source code in `nodes` and `red`. + +`test/resources` is used for storing files that are needed to run a test script. For example, `70-HTML-test-file.html` is used in `70-HTML_spec.js`. +This directory is also used for creating a temporary directory and/or file (e.g. `50-file_spec.js`). + +### Checking the existence of test cases for core components +`test/_spec.js` traverses under a `red` directory to check if all .js files have a corresponding `_spec.js` test file. +When adding a code in `red` directory, the corresponding test file also needs to be created. + +### Testing environment +When you develop a feature that depends on OS or browser, please test on the following environments according to the modification. + +OS +- Linux (Ubuntu, Raspbian, etc.) +- Mac OS X +- Windows + +Browser +- Chrome +- Safari +- Internet Explorer +- Firefox + + +*** +# Helper node + +There is a helper script for testing a node `test/nodes/helper.js`. When testing a node, it is recommended to use this script. +Helper script can start Node-RED server, load a flow, and receive a payload from the previous node, etc. + +### Starting a server +`helper.startServer` starts a Node-RED server. To start a Node-RED server on each test case: +``` + beforeEach(function(done) { + helper.startServer(done); + }); +``` + +### Loading a flow +`helper.load` loads a flow then starts the flow. This function has the following arguments in order. + +- `testNode`: (object|array of objects) Module object of a node to be tested returned by require function. This node will be registered, and can be used in `testFlows`. +- `testFlows`: (array of objects) [Flow data](https://github.com/node-red/node-red/wiki/Flow-Format) to test a node. If you want to use the flow data exported from Node-RED editor, need to covert it to JavaScript object using JSON.parse(). +- `testCredentials`: (object) [Node credentials](https://nodered.org/docs/creating-nodes/credentials). This argument is optional. +- `cb`: (function) Function to call back when testFlows has been started. + +The minimum script to test a flow is as follows. This case omits `testCredentials`. +``` + var testNode = require("../../../../nodes/core/core/20-inject.js"); + it('should be loaded', function(done) { + var testFlows = [{id:"n1", type:"inject"}]; + helper.load(testNode, testFlows, function() { + var n1 = helper.getNode("n1"); + done(); + }); + }); +``` + +### Receiving a message +`helper.getNode` returns a node instance. Any node that is defined in `testFlows` can be retrieved, including `helper` node that is automatically registered when a flow is loaded. +Helper node is a mock node with no functionality. By adding "input" event, the helper node can receive a message from the previous node and check if its contents are the expected value. + +The following is a sample test case to check a message that is sent from `inject` node. +Once the flow is loaded, "n1" inject node sends a message to "n2" helper node. "n2" node receives a message and checks if the payload is correct. + +``` + it('should send a message', function(done) { + var testFlows = [ + {id:"n1", type:"inject", payload:"hello world!", once: true, wires:[["n2"]] }, + {id:"n2", type:"helper"} + ]; + helper.load(testNode, testFlows, function() { + var n2 = helper.getNode("n2"); + n2.on("input", function(msg) { + msg.should.have.property('payload', 'hello world!'); + done(); + }); + }); + }); +``` + +### Unloading a flow +`helper.unload` clears node registration and context, then stops a flow. + +### Stopping a server +`helper.stopServer` stops a Node-RED server. +To unload a flow then stop a server: + +``` + afterEach(function(done) { + helper.unload().then(function() { + helper.stopServer(done); + }); + }); +``` + +*** +# Testing Node-RED + +### Running a test +You can run test scripts with `grunt` command in the `node-red` directory that is cloned from GitHub. + +The following table shows the options for this command. + +Option | Description +-------------|------------- +`default` | Builds editor content then runs code style checks and unit tests on all components. `default` means to run `grunt` command without option. +`test-core` | Runs code style check and unit tests on core runtime code. +`test-editor`| Runs code style check on editor code. +`test-nodes` | Runs unit tests on core nodes. +`clean` | Deletes build outputs +`build` | Builds editor contents +`dev` | Developer mode: runs node-red, watches for source changes and rebuilds/restart +`coverage` | Runs unit tests on all components, and outputs coverage reports. +`release` | Creates distribution zip file - this is the content that will get published to npm when do a release and make available as a zip download via GitHub. + +### Testing runtime +Runtime consists of `nodes` and `red` directories. +When modified these components, the associated test file should be modified or created if not exists. + +#### Running a specific test file +To run only a specific test script, run the following command in the `node-red` directory: + +``` + npm install -g mocha + mocha test/nodes/core/core/20-inject_spec.js +``` + +If you cannot install mocha command globally, run the following command as an alternative: + +``` + node node_modules/mocha/bin/mocha test/nodes/core/core/20-inject_spec.js +``` + +#### Checking a coverage report +If a pull request causes the code coverage to decrease it will be rejected unless there is a good reason provided. To run all test cases and output coverage report: + +``` + grunt coverage +``` + +Once all tests finished, open `index.html` in `coverage/lcov-report` directory to see the coverage report. +If the source code that you developed is all covered by test cases, it is ok to send a pull request. + +### Testing editor +Currently, there is no test scripts for Node-RED editor. When you modify Node-RED editor, you need to test by hand. +You can run Node-RED with the following command to not minify and uglify scripts so that you can view a code on a browser debugger. + +``` + grunt dev +``` + +### Sending a pull request +After finishing the above procedure, it is ready to send a pull request. Please read [Contributing to Node-RED](https://nodered.org/about/contribute/) again before sending a pull request.