Giter Site home page Giter Site logo

nordcloud / serverless-mocha-plugin Goto Github PK

View Code? Open in Web Editor NEW
160.0 14.0 51.0 752 KB

Plugin for Serverless Framework which adds support for test-driven development using Mocha

License: MIT License

JavaScript 96.22% HTML 3.78%
serverless-plugin mocha serverless-framework test-driven-development

serverless-mocha-plugin's Introduction

Serverless Mocha Plugin

Build Status

A Serverless Plugin for the Serverless Framework, which adds support for test driven development using mocha

THIS PLUGIN REQUIRES SERVERLESS V1!

More familiar with Jest? Use serverless-jest-plugin.

Introduction

This plugin does the following:

  • It provides commands to create and run tests manually
  • It provides a command to create a function, which automatically also creates a test

Installation

In your service root, run:

npm install --save-dev serverless-mocha-plugin

Add the plugin to serverless.yml:

plugins:
  - serverless-mocha-plugin

Usage

Creating functions

Functions (and associated tests) can be created using the command

sls create function -f functionName --handler handler

e.g.

sls create function -f myFunction --handler functions/myFunction/index.handler

creates a new function myFunction into serverless.yml with a code template for the handler in functions/myFunction/index.js and a Javascript function module.exports.handler as the entrypoint for the Lambda function. A test template is also created into test/myFunction.js. Optionally tests can be created to specific folder using --path or -p switch, e.g.

sls create function -f myFunction --handler functions/myFunction/index.handler --path tests

To create an http event for the lambda, add the --httpEvent parameter, i.e.

sls create function -f myFunction --handler functions/myFunction/index.handler --httpEvent "[httpVerb] [relativePath]"

e.g.

sls create function -f myFunction --handler functions/myFunction/index.handler --httpEvent "post myResource" --httpEvent "get myResource"

Creating tests

Functions can also be added manually using the mocha-create command

sls create test -f functionName

If you want to run the tests against the real Lambda functions, you can initLiveModule() instead of getWrapper(). You can also use --live flag and then you don't need to change your tests.

  let wrapped = mochaPlugin.initLiveModule('myLambdaFunctionName');

initLiveModule() and getWrapper() are helper methods to initialize lambda-wrapper, which is used under the hood. Both methods return wrapped function, which can be invoked with .run({}) method and takes event object as an argument.

Running tests

Tests can be run directly using the "invoke test" command. This also initializes the environment variables based on your serverless.yml file and the SERVERLESS_TEST_ROOT variable that defines the root for the code to be tested. If you're running the tests locally (rather than on live Lambdas, as described below), it will also set the IS_LOCAL to 'true' to match the behavior of sls invoke local.

sls invoke test [--stage stage] [--region region] [-t timeout] [-f function1] [-f function2] [...]

To use a mocha reporter (e.g. json), use the -R switch. Reporter options can be passed with the -O switch.

If no function names are passed to "invoke test", all tests are run from the test/ directory and subdirectories.

The default timeout for tests is 6 seconds. In case you need to apply a different timeout, that can be done in the test file using using .timeout(milliseconds) with the define, after, before or it -blocks. e.g.

  it('implement tests here', () => {
    ...
  }).timeout(xxx);

To run test in specific folder use --path or -p switch.

To run tests live against the actual deployed Lambdas, use the '--live' or '-l' switch. Please note that this will work only for tests created with module version 1.4 or higher.

To run tests e.g. against built artefacts that reside in some other directory, use the '--root' or '-r' switch. e.g.

  sls webpack -o testBuild
  sls invoke test --root testBuild
  rm -rf testBuild

Using own template for a test file

The templates to use for new function Files can be determined with the custom testTemplate configuration in serverless.yml

custom:
  serverless-mocha-plugin:
    testTemplate: templates/myTest.js

Currently, there are three variables available for use in the template:

  • functionName - name of the function
  • functionPath - path to the function
  • handlerName - the name of the handler function

If you'd like to get more information on the template engine, you check documentation of the EJS project.

Using own template for function file

The templates to use for new function Files can be determined with the custom functionTemplate configuration in serverless.yml

custom:
  serverless-mocha-plugin:
    functionTemplate: templates/myFunction.js

Running commands before / after tests

The plugin can be configured to run commands before / after the tests. This is done by setting preTestCommands and postTestCommands in the plugin configuration.

For example, start serverless-offline before tests and stop it after tests using the following configuration:

custom:
  serverless-mocha-plugin:
    preTestCommands: 
      - bash startOffline.sh
    postTestCommands:
      - bash stopOffline.sh

Sample startOffline.sh:

TMPFILE=/var/tmp/offline$$.log
if [ -f .offline.pid ]; then
    echo "Found file .offline.pid. Not starting."
    exit 1
fi

serverless offline 2>1 > $TMPFILE &
PID=$!
echo $PID > .offline.pid

while ! grep "server ready" $TMPFILE
do sleep 1; done

rm $TMPFILE

Note: The example relies on the output of the serverless offline command. If the start script is not working for you, replace "server ready" with the string serverless offline prints as soon as the server is ready and listening.

Sample stopOffline.sh

kill `cat .offline.pid`
rm .offline.pid

Usage with babel register

If you use mocha with babel compiler e.g. sls invoke test --compilers js:@babel/register
Babel configuration can be determined with the custom babelOptions configuration in serverless.yml

custom:
  serverless-mocha-plugin:
    babelOptions:
      presets: [["@babel/env", { "targets": { "node": "8.10" }, "shippedProposals": true, "useBuiltIns": "usage" }]]
      plugins:
        - ["@babel/plugin-transform-runtime"]

Release History (1.x)

  • 2019/11/xx - v1.12.0 - support for node12 fix --compiler option parsing
  • 2019/07/25 - v1.11.0 - support for node10 deprecated node6
  • 2019/04/02 - v1.10.0 - add timeout parameter add babel options
  • 2018/12/15 - v1.9.1 - fix to work with serverless 1.33 and later
  • 2018/09/16 - v1.9.0 - add support for --exit option
  • 2018/04/03 - v1.8.0 - add support for Node 8
  • 2017/09/10 - v1.7.0 - ability to run scripts before / after tests
  • 2017/09/09 - v1.6.0 - also run tests from subfolders of test
  • 2017/07/11 - v1.4.1 - Add option --root for running tests on e.g. webpack build results residing in other directories, add option --httpEvent to create http events when creating functions
  • 2017/07/09 - v1.4.0 - Add --live switch, add --grep switch, verify that the test runtime matches the service runtime, upgrade lambda-wrapper (returns exceptions as errors)
  • 2016/12/21 - v1.3.2 - Fix population of environment variables
  • 2016/11/28 - v1.3.1 - Added support for environment variables in Serverless 1.2
  • 2016/11/09 - v1.2.0 - Added ability to add function / test templates
  • 2016/11/09 - v1.1.0 - Added function create command.
  • 2016/09/23 - v1.0.2 - Bugfixes, configurable test timeouts
  • 2016/08/15 - v1.0.0 - Preliminary version for Serverless 1.0

License

Copyright (c) 2017 Nordcloud, licensed for users and contributors under MIT license. https://github.com/nordcloud/serverless-mocha-plugin/blob/master/LICENSE

serverless-mocha-plugin's People

Contributors

0xkalle avatar alexdebrie avatar aniako avatar c0d3d avatar christopherchubb avatar dependabot[bot] avatar ecoruh avatar karihe avatar laardee avatar marcoonroad avatar martinheidegger avatar michaelmoussa avatar mpuittinen avatar mrosack avatar nielsgl avatar oipat avatar pcowgill avatar rafaljanicki avatar remedialchaostheory avatar ryof avatar seketman avatar tdi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serverless-mocha-plugin's Issues

Create test for existing function doesn't work

Trying to create a test for an existing function in a folder.

$ sls function mocha-create myFunction

Unhandled rejection TypeError: Cannot read property 'split' of undefined
    at .../node_modules/serverless-mocha-plugin/index.js:155:50
    at tryCatcher (.../node_modules/serverless-mocha-plugin/node_modules/bluebird/js/release/util.js:11:23)
    at Promise._settlePromiseFromHandler (.../node_modules/serverless-mocha-plugin/node_modules/bluebird/js/release/promise.js:489:31)
    at Promise._settlePromise (.../node_modules/serverless-mocha-plugin/node_modules/bluebird/js/release/promise.js:546:18)
    at Promise._settlePromiseCtx (.../node_modules/serverless-mocha-plugin/node_modules/bluebird/js/release/promise.js:583:10)
    at Async._drainQueue (.../node_modules/serverless-mocha-plugin/node_modules/bluebird/js/release/async.js:134:12)
    at Async._drainQueues (.../node_modules/serverless-mocha-plugin/node_modules/bluebird/js/release/async.js:139:10)
    at Immediate.Async.drainQueues [as _onImmediate] (.../node_modules/serverless-mocha-plugin/node_modules/bluebird/js/release/async.js:16:14)
    at processImmediate [as _immediateCallback] (timers.js:383:17)

Run all tests in test folder

Today the plugin only run tests with matching function names. Would be great if the plugin ran all tests inside test folder on "sls invoke test".

I've tried running tests directly with mocha but then I need to export environment variables that were on serverless.yml.

Conflicting with the core `sls invoke` command (v1)

Once I've added this plugin to my Serverless (v1) project, I can't invoke my function via the usual "serverless invoke -f hello" command. I get this debug output:

$ serverless invoke -f hello

  Type Error ---------------------------------------------

     Cannot read property 'forEach' of undefined

     For debugging logs, run again after setting SLS_DEBUG env var.

  Stack Trace --------------------------------------------

TypeError: Cannot read property 'forEach' of undefined
    at PluginManager.getEvents (/Users/rowan/.nvm/versions/node/v4.3.2/lib/node_modules/serverless/lib/classes/PluginManager.js:216:39)
    at PluginManager.run (/Users/rowan/.nvm/versions/node/v4.3.2/lib/node_modules/serverless/lib/classes/PluginManager.js:77:25)
    at Serverless.run (/Users/rowan/.nvm/versions/node/v4.3.2/lib/node_modules/serverless/lib/Serverless.js:77:33)
    at /Users/rowan/.nvm/versions/node/v4.3.2/lib/node_modules/serverless/bin/serverless:18:50

Looking closer, the commandDetails variable in PluginManager.js (line 216) at run time is:

{ usage: 'Invoke mocha tests for service / function',
  commands:
   { test:
      { usage: 'Invoke test(s)',
        lifecycleEvents: [Object],
        options: [Object] } } }

I'm just getting started with Serverless, but it looks like it's not expecting this object to have so many levels (i.e. it's expecting the lifecycleEvents property to be at the top level of commandDetails).

Is this a configuration issue on my side? I'm adding this snippet at the bottom of my serverless.yml file to load the plugin:

plugins:
  - serverless-mocha-plugin

If I don't load this plugin, the invoke command works as expected.

Errors are not being caught what leads to timeouts

Hello,

When running async tests (= all which are related to sls) and when an assertion fails, the test is doing timeout instead of reporting the error directly. In order to catch the error, we'd have to do try-catch block around every callback.

Do you have any other solution for this? Shouldn't it be caught by the plugin or lambdaWrapper?

Tests in a directory other than 'test'

How can I run tests that are not in the 'test' directory, either in a different hierarchy or a subdirectory of test? Using serverless-mocha-plugin 0.5.6 with serverless 0.5.5, I tried

sls function mocha-run path/to/tests

but that gave

Unhandled rejection Error: Cannot find module '...\test\path\to\tests.js'

In other words, it always starts with 'test'. I then tried putting path/to/tests below test, and referred to the test file name (mytest.js) like this:

sls function mocha-run path/to/tests/mytest

then got

...\node_modules\bluebird\js\release\async.js:61
        fn = function () { throw arg; };
                           ^

TypeError: Cannot read property 'toObjectPopulated' of undefined
  at ...\node_modules\serverless-mocha-plugin\index.js:206:54

Examples

Is there a place where I can find examples?

I have the local dynamodb plugin configured and running, is it possible to start it via sls invoke test?

Thanks

How to run ES6 functions?

Is there a way to run functions that rely on ES6 and compile them via Bable before testing?

As of now i do get the following error running sls function mocha-run.
Do i misinterpret the error and this is unrelated of ES6?

Unhandled rejection SyntaxError: Unexpected reserved word
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (/Users/richardrentrop/Desktop/JS/auto-scraper/api/scrape/website/handler.js:4:11)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at Object.<anonymous> (/Users/richardrentrop/Desktop/JS/auto-scraper/test/scrape-website.js:4:11)
    at Module._compile (module.js:409:26)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Module.require (module.js:353:17)
    at require (internal/module.js:12:17)
    at /Users/richardrentrop/Desktop/JS/auto-scraper/node_modules/mocha/lib/mocha.js:192:27
    at Array.forEach (native)
    at Mocha.loadFiles (/Users/richardrentrop/Desktop/JS/auto-scraper/node_modules/mocha/lib/mocha.js:189:14)
    at Mocha.run (/Users/richardrentrop/Desktop/JS/auto-scraper/node_modules/mocha/lib/mocha.js:422:31)
    at /Users/richardrentrop/Desktop/JS/auto-scraper/node_modules/serverless-mocha-plugin/index.js:122:21
    at tryCatcher (/Users/richardrentrop/Desktop/JS/auto-scraper/node_modules/serverless-mocha-plugin/node_modules/bluebird/js/release/util.js:11:23)
    at Promise._settlePromiseFromHandler (/Users/richardrentrop/Desktop/JS/auto-scraper/node_modules/serverless-mocha-plugin/node_modules/bluebird/js/release/promise.js:489:31)

Add support for the --recursive option

I'd like to organize my functions and tests similarly. For example:

|--functions
|  |--namespace
|     |--handler.js
|     |--helper.js 
|--test
|  |--namespace
|     |--handler.test.js
|     |--helper.test.js

The way this plugin constructs the arguments to mocha currently results in no tests being found when the structure above is being used. Mocha has a command line option, --recursive to allow running all tests recursively under a directory.

This plugin should recognize this as an option and pass it through to the mocha process, similar to how it does for --compilers

Pass context object to lamdba wrapper

Hi there! Is it possible to pass the context object to my lambda function?

I'd like to test the Cognito User Pool Identity but API Gateway passes it in the context object.

Thanks!

TypeError: this.timeout is not a function

The default timeout for tests is 6 seconds. In case you need to apply a different timeout, that can be done in the test file using using this.timeout(milliseconds) in the define, after, before or it -blocks.

I'm trying the extent the timeout but keep getting TypeError: this.timeout is not a function. Are the docs out of date?

'use strict';

// tests for mapServicePrint
// Generated by serverless-mocha-plugin

const mod = require('../handlers.js');
const mochaPlugin = require('serverless-mocha-plugin');

const lambdaWrapper = mochaPlugin.lambdaWrapper;
const expect = mochaPlugin.chai.expect;
const wrapped = lambdaWrapper.wrap(mod, { handler: 'print' });

describe('mapServicePrint', () => {

  before((done) => {
//  lambdaWrapper.init(liveFunction); // Run the deployed lambda

    done();
  });

  it('should return 200', (done) => {
    this.timeout(30000); // <--- ******
    return wrapped.run({}).then((response) => {
      expect(response.statusCode).to.be.equal(200);
      expect(response).to.not.be.empty;
      done();
    });
  });
});

`sls invoke test` is checking for files in `node_modules`

Versions:
serverless: 1.21.1
serverless-mocha-plugin: 1.7.0

Problem:
I just followed the documentation to add tests to my existing serverless project. I use sls invoke test -p . to run tests and get the following error:

Aruns-MacBook-Pro:aws arunshankar$ sls invoke test -p .
Serverless: Invoke invoke:test
 
  Error --------------------------------------------------
 
  Cannot find module 'nock'
 
     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
 
  Stack Trace --------------------------------------------
 
Error: Cannot find module 'nock'
    at Function.Module._resolveFilename (module.js:469:15)
    at Function.Module._load (module.js:417:25)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/arunshankar/layer/integrations/serverless-email-fallback/aws/node_modules/@layerhq/serverless-common/tests/api.spec.js:3:14)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at /Users/arunshankar/layer/integrations/serverless-email-fallback/aws/node_modules/mocha/lib/mocha.js:231:27
    at Array.forEach (native)
    at Mocha.loadFiles (/Users/arunshankar/layer/integrations/serverless-email-fallback/aws/node_modules/mocha/lib/mocha.js:228:14)
    at Mocha.run (/Users/arunshankar/layer/integrations/serverless-email-fallback/aws/node_modules/mocha/lib/mocha.js:514:10)
    at vars.populateService.then.then.then.then (/Users/arunshankar/layer/integrations/serverless-email-fallback/aws/node_modules/serverless-mocha-plugin/index.js:295:19)
    at runCallback (timers.js:651:20)
    at tryOnImmediate (timers.js:624:5)
    at processImmediate [as _immediateCallback] (timers.js:596:5)
From previous event:
    at serverless.service.load.then (/Users/arunshankar/layer/integrations/serverless-email-fallback/aws/node_modules/serverless-mocha-plugin/index.js:206:12)
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
 
  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           6.10.0
     Serverless Version:     1.21.1

Am I doing something wrong? Or can I exclude node_modules from my tests?

Command does not exit after running tests

After following instructions, I wrote a couple of tests, and after I run them with
SLS_DEBUG=* sls invoke test --stage ci -f githubNotify --compilers js:babel-register
the tests pass, but the process will not exit (I need to Ctrl+C to force it).

Tests are as follows:

describe('githubNotify', () => {
  it('should return a HTTP 200 response', async () => {
    const result = await wrapped.run(payload);
    expect(result).to.have.property('statusCode', 200);
  });

  it('should throw error if payload is invalid', () => {
    expect(wrapped.run).to.throw();
  });
});

Other than that and commenting out the before() function, I did not modify the template.
I verified that my function returns as expected in both cases, and even if I run each test separately, both get stuck after passing.

Is there anything I'm missing?

Serverless `create test` command fails with `Cannot read property 'handler' of undefined`

Tried to create test for existing function and got error:

$ SLS_DEBUG=* sls create test -f getDevices
 
  Type Error ---------------------------------------------
 
     Cannot read property 'handler' of undefined
 
     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
 
  Stack Trace --------------------------------------------
 
TypeError: Cannot read property 'handler' of undefined
    at utils.createTestFolder.then (/home/sls/node_modules/serverless-mocha-plugin/index.js:223:32)
    at tryCatcher (/home/sls/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/sls/node_modules/bluebird/js/release/promise.js:510:31)
    at Promise._settlePromise (/home/sls/node_modules/bluebird/js/release/promise.js:567:18)
    at Promise._settlePromise0 (/home/sls/node_modules/bluebird/js/release/promise.js:612:10)
    at Promise._settlePromises (/home/sls/node_modules/bluebird/js/release/promise.js:691:18)
    at Async._drainQueue (/home/sls/node_modules/bluebird/js/release/async.js:138:16)
    at Async._drainQueues (/home/sls/node_modules/bluebird/js/release/async.js:148:10)
    at Immediate.Async.drainQueues (/home/sls/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:672:20)
    at tryOnImmediate (timers.js:645:5)
    at processImmediate [as _immediateCallback] (timers.js:617:5)
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
 
  Your Environment Information -----------------------------
     OS:                 linux
     Node Version:       7.10.0
     Serverless Version: 1.14.0

Testing with invoke local?

Very interested in the approach here - and learning from your experience... I currently use mocha to test my handlers directly and that seems to work well (e.g. https://github.com/activescott/sheetmonkey-server/blob/master/server/test/tests/PluginsHandler.js). The approach in this plugin is one step closer to production since it more closely emulates invocation via lambda. However, the thing I find myself frequently overlooking with my current testing isn't covered by the approach in this plugin.

The tests I have now do not validate that I have my serverless.yml in sync with the code itself. I was thinking of doing this by having the mocha tests use serverless invoke local to test the http event bindings in addition to the code itself. Just curious if you have thought about this more than I have and rule it out - maybe I'm missing something?

Support for New NodeJS 4.3.2 Lambda API

I am having issues running tests using the new Lambda API. The error I see is

TypeError: cb is not a function

It appears this may be due to using an older version of lambda-wrapper.

I am doing something wrong or does lambda-wrapper version need to updated?

What else does this plugin do?

This is a questions and maybe a documentation update request.

From docs we have:

This plugins does the following:

It provides commands to create and run tests manually
It provides a command to create a function, which automatically also creates a test

Seems that the plugin also loads environment variables from serverless.yml. If it was only for the aliases commands mentioned I would be using plain mocha instead. So I was wondering, are there any other differences between running the tests with plain mocha and running it with sls invoke test?

Running multiple test function files

When i try to run multiple test files at a time it uses the last function (alphabetical order) for all the functions instead of using their respective functions

Unable to run the tests on NodeJs version 7.7

I'm not able to run any simple tests, My NodeJS version 7.7.2

node --version
v7.7.2

sls invoke test
(node:8634) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: vars.populateService(...).then is not a function

Here is my test code -

'use strict';
// tests for SensorApi
// Generated by serverless-mocha-plugin
const mod = require('../index.js');
const wrapper = mochaPlugin.lambdaWrapper;
const mochaPlugin = require('serverless-mocha-plugin');
const expect = mochaPlugin.chai.expect;
const wrapped = wrapper.wrap(mod, {handler: 'apiHandler'})

describe('SensorApi', () => {
  before((done) => {
    done();
  });

  it('validate status code', () => {
    return wrapped.run({
    	method: 'POST',
    	resource: '/v1/coursa/sdk/sensor/pressure',
    	headers:{
    		'x-api-key': "GLVNNI5UKKaG2WG3icN7Mabg48HWUB3oagYa70bM"
    	},
    	body: {
    		lng:-121.9201652427408,
    		lat:37.36831249207013,
    		os:"10.3.3",
    		alt:0,
    		platform:"iOS",
    		pressure:101038.2,
    		time:1502221435.013941,
    		device:"Unit Test Case",
    		acc:10
    	}
    }).then((response) => {
    	const body = JSON.parse(response.body);
    	expect(response.statusCode).to.be.equal(200);
    });
  });
});

Switch back to "classical" function calls in test template

From mocha.js documentation:
"Passing arrow functions (“lambdas”) to Mocha is discouraged. Due to the lexical binding of this, such functions are unable to access the Mocha context. For example, the following code will fail due to the nature of lambdas:"

We've had e.g. issues related to this.timeout() because of this. Let's revert to "regular" function calls instead of arrow functions to have the mocha context available in tests. (opinions @laardee ?)

Passing event object to the lambda function

Is it possible to pass the event object in form of the .json file to the lambda function being tested?

export default async (event, context, callback) => {
  try {
    const result = await someAsyncFunction(event);
    callback(null, result);
  } catch (err) {
    callback(err);
  }
};

Referenced variables in serverless.yml not expanded during invoke test

Hello,

I am quite confused to this as I am still very new to serverless and TDD for serverless, however, in my serverless.yml, I have declared

provider:
  name: aws
  region: 'ap-northeast-1' 

where under the same provider, I have also written

environment:
    region: ${opt:region,self:provider.region}

However, over in my nodejs function, when I retrieve the variable via process.env.region to use in the AWS SDK, instead of 'ap-northeast-1' , I got ${opt:region,self:provider.region}.

I also got the error when I following error when I try to use the RDS API

err# {"message":"Inaccessible host: rds.'. This service may not be available in the ${opt:region,self:provider.region}' region.

May I know if this is supposed to happen? I know that the variable references are correctly declared as it works perfectly fine when deployed..

sls invoke test error

When I run the command sls invoke test I receive the following error:

Type Error ---------------------------------------------
 
     vars.populateService(...).then is not a function
 
     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
 
  Stack Trace --------------------------------------------
 
TypeError: vars.populateService(...).then is not a function
    at serverless.service.load.then (/...omitted.../node_modules/serverless-mocha-plugin/index.js:147:12)
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
 
  Your Environment Information -----------------------------
     OS:                 darwin
     Node Version:       6.5.0
     Serverless Version: 1.12.1

I found a change in the same line of index.js file, referenced in the commit 70c1ee761b6c751be6a70969466a48ceae09fb9d, that generated the version 1.3.6.

I try the version 1.3.5 and have no errors.

example ?

anyone got an example serverless project that uses this plugin, cannot get it to run

have added this to package.json

"scripts": {
"test": "SLS_DEBUG=true serverless --stage dev invoke test"
}

and when i run npm test I get this:

**Serverless Error ---------------------------------------

 Trying to populate non string value into a string for
 variable ${opt:stage}. Please make sure the value of
 the property is a string.

Stack Trace ---**

heres my serverless.yml

service: email-integration

You can pin your service to only deploy with a specific Serverless version

Check out our docs for more details

frameworkVersion: "=X.X.X"

provider:
name: aws
apiKeys:
- ${opt:stage}-${self:service}-api-key
runtime: nodejs4.3

you can overwrite defaults here

stage: ${opt:stage} # Set the default stage used. Default is dev
region: eu-west-1 # Overwrite the default region used. Default is us-east-1

you can add statements to the Lambda function's IAM Role here

iamRoleStatements:
- Effect: "Allow"
Action:
- "sqs:"
Resource: "arn:aws:sqs:
::${opt:stage}-emailtaskqueue" #allow access to queue
- Effect: "Allow"
Action:
- "lambda:
"
Resource: "*" #allow to invoke other lambdas

environment:
ACCOUNT_ID : xxxxxx #813371197456 #644843699445
STAGE : ${opt:stage}
REGION : ${self:provider.region}
SERVICE : ${self:service}

you can add packaging information here

package:
include:

- emailRequestListener/handler.js

- include-me-dir/**

exclude:
- emailRequestListener/test/**

- exclude-me-dir/**

functions:

hello:
handler: handler.hello
events:
- http:
path: hello
method: get

emailRequestListener: #api gateway listening for incoming sendEmail requests
handler: emailRequestListener/handler.emailRequestListener
events:
- http:
path: sendEmail
method: post
private: false

emailTaskConsumer: #scheduled lambda that reads messages periodically from SQS queue and delegates to workers
handler: emailTaskConsumer/handler.emailTaskConsumer
timeout: 200 #200 seconds max
events:
- schedule: rate(1 minute)

emailWorker: #worker lambda to call email service provider
handler: emailWorker/handler.emailWorker

plugins:
- serverless-mocha-plugin

you can add CloudFormation resource templates here

resources:
Resources:

EmailTaskDeadLetterQueue:   #email task dead letter queue
  Type: 'AWS::SQS::Queue'
  Properties:
    MessageRetentionPeriod: 1209600
    QueueName: ${opt:stage}-emailtaskdeadletterqueue

EmailTaskQueue:  #email task queue
  Type: 'AWS::SQS::Queue'
  Properties:
    MessageRetentionPeriod: 1209600
    QueueName: ${opt:stage}-emailtaskqueue
    VisibilityTimeout : 30
    #RedrivePolicy:
    #    deadLetterTargetArn: arn:aws:sqs:${self:provider.environment.REGION}:${self:provider.environment.ACCOUNT_ID}:${opt:stage}-emailtaskdeadletterqueue
    #    maxReceiveCount: 3

`

Use templates when generating a test file

Hello,

I was thinking about introducing a simple template engine to handle generation of test files as those vary between projects and as sls-mocha-plugin already creates test files, why won't make it more powerful?

The behaviour would be quite simple - if file xxx.yyy exists, use it, otherwise use a predefined template.

For the engine I was thinking about something simple like EJS or doT.js. I haven't tried them yet, but it looks like they're old enough to be used.

What do you think?

Bit of guidance

G'day,

I'm getting started with TDD and want to test outputs from specific methods/functions within a Lambda function. Some of these functions live in separate files in a lib folder. Is this possible? How would I go about this?

Cheers

Environment variables loaded from file

Looks like there is a bug with the way that environment variables are loaded I'm not sure if it's because tests are run to early. But serverless allows for loading Env vars from a variable https://serverless.com/blog/serverless-v1.2.0/?utm_source=Newsletter&utm_medium=Email&utm_campaign=v1.2%20release. Such as

functions:
  myFunction:
    environment:
      apiKey: ${file(../keys.yml):apiKey}

It looks like that when a test is being run it's still being provided ${file(../keys.yml):apiKey} rather than the variable itself.

Serverless v1.0 branch runs the last handler in every test case

Setup:
I have the following handler.js

module.exports.createPost = function createPost(event, context, cb) {
  const blog = new BlogStorage(dynamodb, event.stage);
  console.log('CREATE called');
  blog.savePost(event.body, cb);
};

module.exports.getPosts = function getPosts(event, context, cb) {
  const blog = new BlogStorage(dynamodb, event.stage);
  console.log('GET called');
  blog.getPosts({}, cb);
};

module.exports.updatePost = function updatePost(event, context, cb) {
  const blog = new BlogStorage(dynamodb, event.stage);
  console.log('UPDATE called');
  blog.updatePost(event.path.id, event.body, cb);
};

module.exports.removePost = function removePost(event, context, cb) {
  const blog = new BlogStorage(dynamodb, event.stage);
  console.log('REMOVE called');
  blog.deletePost(event.path.id, cb);
};

Each handler is accompanied by their own test under the test/ folder. The handler references in the wrapper is pointing towards the correct handlers.

wrapper.init(mod, {
  handler: 'createPost'
});

describe('API create', () => {
  it('creates a post', (done) => {
    wrapper.run({
        "method": "POST",
        "stage": "dev",
        "body": {
          "title": "Test post",
          "content" : "Test content"
        }
    }, (err, response) => {
      expect('to be implemented').to.be.null;
      done();
    });
  });
});

Problem

However, when invoking the test set I get this curious result:

  API create
REMOVE called
    1) creates a post

  API get
REMOVE called
    2) reads posts

  API update
REMOVE called
    3) updates a post

  API remove
REMOVE called
    4) deletes a post

Doesn't handle nested folders

When i try to create a function or test where the function is inside a nested folder, it fails to create the directories in the tree up to the folder under test.

sls function create functions/sample/sub/folder
Serverless: Please, select a runtime for this new Function
    nodejs
  > nodejs4.3
    python2.7
Serverless: For this new Function, would you like to create an Endpoint, Event, or just the Function?
    Create Endpoint
    Create Event
  > Just the Function...
Serverless: Successfully created function: "functions/sample/sub/folder"
/usr/local/lib/node_modules/serverless/node_modules/bluebird/js/release/async.js:49
        fn = function () { throw arg; };
                           ^

Error: Creating file test/functions_sample/sub/folder.js failed: Error: ENOENT: no such file or directory, open 'test/functions_sample/sub/folder.js'
    at /Users/nick/Development/sample_project/node_modules/serverless-mocha-plugin/index.js:173:34
    at fs.js:1197:21
    at OpenReq.Req.done (/Users/nick/Development/sample_project/node_modules/graceful-fs/graceful-fs.js:143:5)
    at OpenReq.done (/Users/nick/Development/sample_project/node_modules/graceful-fs/graceful-fs.js:63:22)
    at FSReqWrap.oncomplete (fs.js:83:15)
From previous event:
    at Serverless._execute (/usr/local/lib/node_modules/serverless/lib/Serverless.js:200:19)
    at Serverless.actions.(anonymous function) (/usr/local/lib/node_modules/serverless/lib/Serverless.js:429:20)
    at Serverless.command (/usr/local/lib/node_modules/serverless/lib/Serverless.js:398:38)
    at /usr/local/lib/node_modules/serverless/bin/serverless:19:16
    at processImmediate [as _immediateCallback] (timers.js:384:17)
From previous event:
    at Object.<anonymous> (/usr/local/lib/node_modules/serverless/bin/serverless:18:4)
    at Module._compile (module.js:399:26)
    at Object.Module._extensions..js (module.js:406:10)
    at Module.load (module.js:345:32)
    at Function.Module._load (module.js:302:12)
    at Function.Module.runMain (module.js:431:10)
    at startup (node.js:141:18)
    at node.js:977:3

Tests fail if lambda connecting to private resource

Mocha tests use lambda-wrapper to run functions offline and test the output. If the lambda function needs to connect to a private resource, like an RDS database, the function times out and the test fails. Can the deployed lambda function be invoked instead of running locally?

Force user to set a stage name?

Hey,

I wonder if fetching all stages in case no is provided is safe. E.g. I have an environment set with 3 stages - dev, test & production. And I keep database credentials for each as my tests are executing IT tests as well. If I forgot to provide a stage name, there is a chance that my production database would be purged and filled with test data.

What do you think about forcing user to provide a stage name? Or at least do it in a serverless way and ask a user for the stage.

I can do a PR, but would like to discuss that before

Feature request: way to pass CLI args through to mocha

Say for example I am running my tests with the following command:

sls invoke test -f <function_name>

But I would like to use mocha's feature -g <pattern> flag to only run tests that match a certain pattern, it would be great if there were a way to pass that into my above command and have it passed on to mocha using mocha.setup({ g: pattern }). One complication is that mocha shares some arguments with the package. My suggestion would be to prepend any mocha args with mocha- such that my final command in this example would be:

sls invoke test -f <function_name> -mocha-g <pattern>

If this is already a feature somehow and I missed it looking over the code/doc apologies and any help pointing me in the right direction would be appreciated. Otherwise, I'd be happy to contribute to help get this feature developed if you would like and would appreciate any input.

Thanks!

callback should be optional

In the AWS Lambda docs, calling the callback function is optional, but I find my serverless-mocha-plugin tests don't work unless I call the callback function. Could you please make it optional to match up with AWS?

I was trying to test a lambda that reacts to s3 events, having no need to return anything to the caller.

http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

"callback – You can use the optional callback to return information to the caller, otherwise return value is null."

Code coverage

Does someone has an experience of how to get a code coverage using this plugin?
Would be great to see any ideas or examples if any..

Debugging in vs code

I am unable to debug my mocha tests in vs code. My source files are never loaded. Has anyone tried this ?
What should be the configuration for debugging ?

Cannot run serverless-webpack before tests

cross posted here: serverless-heaven/serverless-webpack#143

Seems like the test runner is not loading other plugins before running the tests. There is a suggestion at the discussion linked above.
@laardee any thoughts on this?

Description

I'm trying to ensure that webpack runs before the testing plugin.

It appears tests are running the uncompiled code (not using webpack), and also using the node version. This means I'm not catching all the syntax errors lambda runtime does not support.

Reproduction

It's a bit tricky to reproduce this error, since you'd have to compare the jest test run results to that of a deployed function.
You can break the webpack integration by breaking the config file :

module.exports = {
  entry: null,
...

The test runner will not catch this error, which implies that webpack is not running before the tests.
The only way to catch this is by running serverless webpack serve

Additional Data

package.json

    "babel-core": "^6.13.2",
    "babel-loader": "^6.2.4",
    "babel-plugin-transform-runtime": "^6.12.0",
    "babel-polyfill": "6.13.0",
    "babel-preset-es2015": "^6.13.2",
    "babel-preset-stage-0": "^6.5.0",
    "serverless-jest-plugin": "^0.1.5",
    "serverless-webpack": "^1.0.0-rc.3",
    "webpack": "^1.13.1"

serverles.yml

plugins:
  - serverless-jest-plugin
  - serverless-webpack

Add verification for serverless Framework version

Verify that the used serverless framework is compatible with the plugin and throw error in case it is too old (to minimize issues related to obsolete versions of serverless being used with the plugin)

Cannot find module

I followed your README. I have a very simple function function1 (created via serverless tutorial). I ran mocha-create and mocha-run commands under serverless project root.

Creation worked OK:

$ sls function mocha-create function1
serverless-mocha-plugin: created test\function1.js

However mocha-run returned this error:

$ sls function mocha-run function1
Unhandled rejection Error: Cannot find module '../functions♀unction1/handler.js'

note: the module has this funny character in stead of /f.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.