UNPKG

runas-core

Version:

The adhesive orchestrator

313 lines (231 loc) 8.84 kB
--- title: Testing layout: doc_page.html order: 16 --- # Testing Runas There are to ways to test runas recipes: `unit testing` and `functional testing (integration)`. Both could be functional but the main difference is that `unit testing` runs as a node library inside the test and `functional testing (integration)` runs the recipe as a system executable using require('child_process').exec. 1. [Unit Testing](#unitTesting) 1. [Functional Testing (integration)](#functionalTesting) ## <a name="unitTesting"></a> Unit testing 1. [Testing steps](#testingSteps) 1. [Testing plugins](#testingPlugins) 1. [Testing contexts](#testingContexts) Needed to test `steps`, `plugins` (coming soon) and `contexts` (coming soon) - These tests reside on the `test` folder of a recipe module. - It just needs the recipe to be tested and its dependencies. - You could generate coverage with this kind of tests ### <a name="testingSteps"></a> Testing steps Steps only need dependency to runas on devDependencies. Add dependencies to mocha and chai too. `NOTE:` If you need a context definition for the step execution, then the dependency to the context has to be on devDependencies too. for example `runas-contexts` package.json: ```json { "...":"...", "scripts": { "deps": "npm install", "test": "node_modules/.bin/mocha -u tdd --recursive" }, "devDependencies": { "chai": "*", "mocha": "*", "runas": "^1.0.0" }, "...":"..." } ``` Writing a test for runas. First require stepTester ```javascript const tester = require('runas/lib/tests/stepTester'); ``` 1. [command object](#command) 1. [setLoggerLevel(level) method](#setLoggerLevel) 1. [loadStep(command) method](#loadStep) 1. [runStep(command) method](#runStep) #### <a name="command"></a>command object. The command object is the configuration parameter that runas uses to run the test. | Param | Type | Optional | Description | | --- | --- | --- | --- | | name | String | No | The name of the step | | context | Array | Yes | Array of the contexts runned | | baseDir | String | Yes | Folder where the step is going to be runned. Default is the root of the recipe. | | params | Object | Yes | All params passed for the execution | #### <a name="setLoggerLevel"></a>setLoggerLevel(level) method `logger.setLoggerLevel(level)` set logger level for runas. [See logger for more information](./14-logger.md) | Param | Type | Optional | Description | | --- | --- | --- | --- | | level | Number | No | 0...5 log levels | #### <a name="loadStep"></a>loadStep(command) method `logger.loadStep(command)` Load local step with all plugins and all runas configuration. **Returns** step object with all runas features loaded. | Param | Type | Optional | Description | | --- | --- | --- | --- | | command | Object | No | See [command object](#command) | #### <a name="runStep"></a>runStep(command) method `logger.runStep(command)` Run one local step from the recipe. **Returns** a promise with the execution of the step. | Param | Type | Optional | Description | | --- | --- | --- | --- | | command | Object | No | See [command object](#command) | This is a example of an entire test file. ```javascript 'use strict'; const path = require('path'); const tester = require('runas/lib/tests/stepTester'); const expect = require('chai').expect; const assert = require('assert'); /* global define, it, describe, before, beforeEach, afterEach, after */ // configure tester.setLoggerLevel(0); // constants const stepName = 'askHello'; const contexts = ['world']; const message = 'Unit Framework hola!'; describe('Unit testing framework for askHello step', () => { it('Should return the step to test', (done) => { const step = tester.loadStep({ name: stepName, context: contexts }); expect(step).not.equal(null); expect(step.name).to.equal(stepName); done(); }); it('Should run the step to test', (done) => { tester.setLoggerLevel(0); tester.runStep({ name: stepName, context: contexts, baseDir: path.join(__dirname, 'world'), params: { paramInquire: message } }) .then(() => { done(); }) .catch((err) => { done(err); }) }); it('Should run the step with plugins to test', (done) => { tester.setLoggerLevel(0); tester.runStep({ name: 'emittingHello', context: contexts, baseDir: path.join(__dirname, 'world'), params: { paramInquire: message } }) .then(() => { done(); }) .catch((err) => { done(err); }) }); }); ``` ### <a name="testingPlugins"></a> Testing plugins (comming soon) ### <a name="testingContexts"></a> Testing contexts (comming soon) ## <a name="functionalTesting"></a> Functional testing (integration) 1. [Configure the recipe](#configureRecipe) 1. [Writing tests](#writeTest) 1. [Running tests](#runningTest) The functional testing features are: - It is used to test only recipes by executing externally all its commands. - It is possible to test `flows` and `steps`. - Executes the recipe command so a configured environment is needed. - Tests are located on an external module, outside of the recipe. Test modules have to be dependencies of the recipe. ### <a name="configureRecipe"></a> Configuring the recipe for testing 1. Add `"test" : "bin/runas.js -ft"` to the `scripts` object in package.json. 1. Add dependencies to one or more functional-testing modules. Fragment of package.json of a recipe. ```json { "scripts": { "deps": "npm install", "test": "bin/runas.js -ft" }, "keywords": [ "runas-recipe" ], "bin": { "cells": "bin/runas.js" }, "dependencies": { "runas": "^1.1.0" }, "devDependencies": { "runas-functional-tests": "^1.0.1-beta" }, "...":"..." } ``` ### <a name="writeTest"></a> Writing the tests (the functional testing module) - This module must have `functional-tests` keyword - Dependencies to testing frameworks should be on dependencies not on devDependencies - Dependency to runas is not necessary. Fragment of package.json of the functional testing module: ```json { "...":"...", "keywords": [ "functional-tests" ], "dependencies": { "chai": "*", "mocha": "*" }, "...":"..." } ``` Now tests must execute the command `runasExec` that is injected as an environment variable. This is an example of tests that we can be written. This test proves the creation of an app using cells-cli recipe. ```javascript 'use strict'; const pctp = require('runas-callback-to-promise'); const u = require('../utils'); const fs = require('fs-extra'); const path = require('path'); const exec = require('child_process').exec; /* global define, it, describe, before, beforeEach, afterEach, after */ // constants const baseApp = `${__dirname}/../tmp`; // ---- Tests -------- describe('Run cells app:create', function() { const allOk = '[ create ] finished'; this.timeout(6000); it(`Should create a list of apps and say "${allOk}" on all apps`, function(done) { pctp.c2p(fs.ensureDir, baseApp) .then(() => pctp.c2p(exec, `${process.env.runasExec} app:create --scaffoldDir scaffold --appName test-app`, {cwd: baseApp})) .catch((err) => pctp.logError(err, done)); }); afterEach('Should delete the tmp directory', (done) => { u.remove([ baseApp ]) .then(() => done()); }); }); ``` Let's see this example: - Note that executable is a env variable: `process.env.runasExec` - We are using pctp module that converts callbacks to promises. ### <a name="runningTest"></a> Running functional tests - From the recipe just with `npm test` or `bin/runas.js -ft` - In the functional testing module just executing mocha. First is needed to export the runasExec parameter to environment: ```bash export runasExec="node /Users/sbonacho/projects/cells-cli/bin/runas.js" mocha -u tdd --recursive test --timeout 5000 --grep "Unit testing framework for askHello step" ``` `NOTE:` Is possible to test docker by changing `runasExec` value: ```bash export runasExec="docker run -ti --rm -p 8000-8100:8000-8100 -p 3000-3100:3000-3100 -v ~/.gradle:/home/runas/.gradle -v ~/.bowerrc:/home/runas/.bowerrc -v ~/.npmrc:/home/runas/.npmrc -v ~/.netrc:/home/runas/.netrc -v ~/.ssh:/home/runas/.ssh -v `pwd`:/home/runas/workspace runas/cells-bundle" ``` The execution of `runas -ft` or `runas --functionalTests` starts with these messages on stdout. Showing the number of functional testing modules in the recipe, theirs names and versions. ```bash [14:32:49] Number of functional testing modules detected: 1 [14:32:49] Executing runas functional tests from runas-functional-tests ( 1.0.15 ) Runas context world validation ✓ Should return .... ```