artillery-plugin-expect
Advanced tools
Comparing version
169
index.js
@@ -0,1 +1,5 @@ | ||
/* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | ||
'use strict'; | ||
@@ -6,4 +10,7 @@ | ||
const chalk = require('chalk'); | ||
const metrics = require('datadog-metrics'); | ||
const EXPECTATIONS = require('./lib/expectations'); | ||
const FORMATTERS = require('./lib/formatters'); | ||
const REPORTERS = require('./lib/reporters'); | ||
module.exports.Plugin = ExpectationsPlugin; | ||
@@ -20,2 +27,5 @@ | ||
script.scenarios.forEach(function(scenario) { | ||
scenario.onError = [].concat(scenario.onError || []); | ||
scenario.onError.push('expectationsPluginOnError'); | ||
scenario.afterResponse = [].concat(scenario.afterResponse || []); | ||
@@ -32,2 +42,3 @@ scenario.afterResponse.push('expectationsPluginCheckExpectations'); | ||
script.config.processor.expectationsPluginCheckExpectations = expectationsPluginCheckExpectations; | ||
script.config.processor.expectationsPluginOnError = expectationsPluginOnError; | ||
@@ -59,17 +70,11 @@ script.config.processor.expectationsPluginSetExpectOptions = function( | ||
const FORMATTERS = { | ||
pretty: prettyPrint, | ||
json: jsonPrint | ||
}; | ||
function expectationsPluginOnError(scenarioErr, requestParams, userContext, events, done) { | ||
if (userContext.expectationsPlugin.outputFormat === 'json') { | ||
console.log(JSON.stringify({ ok: false, error: scenarioErr.message })); | ||
} else { | ||
console.log(chalk.red('Error:'), scenarioErr.message); | ||
} | ||
return done(); | ||
} | ||
const REPORTERS = { | ||
datadog: reportToDatadog | ||
}; | ||
const EXPECTATIONS = { | ||
contentType: expectContentType, | ||
statusCode: expectStatusCode, | ||
hasProperty: expectHasProperty | ||
}; | ||
function expectationsPluginCheckExpectations( | ||
@@ -138,58 +143,6 @@ req, | ||
function prettyPrint(requestExpectations, req, res, userContext) { | ||
console.log( | ||
chalk.blue('*', req.method, urlparse(req.url).path), | ||
req.name ? '- ' + req.name : '' | ||
); | ||
requestExpectations.results.forEach(result => { | ||
console.log( | ||
` ${result.ok ? chalk.green('ok') : chalk.red('not ok')} ${ | ||
result.type | ||
} ${result.got} ` | ||
); | ||
if (!result.ok) { | ||
console.log(' expected:', result.expected); | ||
console.log(' got:', result.got); | ||
console.log(chalk.yellow(' Request params:')); | ||
console.log(prepend(req.url, ' ')); | ||
console.log(prepend(JSON.stringify(req.json || '', null, 2), ' ')); | ||
console.log(chalk.yellow(' Headers:')); | ||
Object.keys(res.headers).forEach(function(h) { | ||
console.log(' ', h, ':', res.headers[h]); | ||
}); | ||
console.log(chalk.yellow(' Body:')); | ||
console.log(prepend(String(JSON.stringify(res.body, null, 2)), ' ')); | ||
console.log(chalk.yellow(' User variables:')); | ||
Object.keys(userContext.vars).forEach(function(varName) { | ||
console.log(' ', varName, ':', userContext.vars[varName]); | ||
}); | ||
} else { | ||
} | ||
}); | ||
} | ||
function jsonPrint(requestExpectations, req, res, userContext) { | ||
console.log(JSON.stringify(requestExpectations)); | ||
} | ||
function reportToDatadog(requestExpectations, req, res, userContext) { | ||
const failedExpectations = | ||
requestExpectations.results.filter(res => !res.ok).length > 0; | ||
const event = | ||
failedExpectations === 0 | ||
? 'request_expectations_passed' | ||
: 'request_expectations_failed'; | ||
userContext.expectationsPlugin.datadog.increment(event, 1, [ | ||
`test-env:${userContext.vars.$env}` | ||
]); | ||
} | ||
function expectationsPluginMaybeFlushDatadog(userContext, events, done) { | ||
if ( | ||
userContext.expectationsPlugin && | ||
userContext.expectationsPlugin.datadog | ||
userContext.expectationsPlugin.datadog | ||
) { | ||
@@ -225,81 +178,1 @@ userContext.expectationsPlugin.datadog.flush( | ||
} | ||
function expectContentType(expectation, body, req, res, userContext) { | ||
debug('check contentType'); | ||
debug('expectation:', expectation); | ||
debug('body:', typeof body); | ||
let result = { | ||
ok: false, | ||
expected: expectation.contentType, | ||
type: 'contentType' | ||
}; | ||
if (expectation.contentType === 'json') { | ||
if ( | ||
typeof body === 'object' && | ||
res.headers['content-type'].indexOf('application/json') !== -1 | ||
) { | ||
result.ok = true; | ||
result.got = 'json'; | ||
return result; | ||
} else { | ||
if (body === null) { | ||
result.got = 'could not parse response body as JSON'; | ||
} else { | ||
result.got = `content-type is ${res.headers['content-type']}`; | ||
} | ||
return result; | ||
} | ||
} else { | ||
result.got = 'Expectations other than "json" are not supported yet'; | ||
return result; | ||
} | ||
} | ||
function expectStatusCode(expectation, body, req, res, userContext) { | ||
debug('check statusCode'); | ||
let result = { | ||
ok: false, | ||
expected: expectation.statusCode, | ||
type: 'statusCode' | ||
}; | ||
result.ok = res.statusCode === expectation.statusCode; | ||
result.got = res.statusCode; | ||
return result; | ||
} | ||
function expectHasProperty(expectation, body, req, res, userContext) { | ||
debug('check hasProperty'); | ||
let result = { | ||
ok: false, | ||
expected: expectation.hasProperty, | ||
type: 'hasProperty' | ||
}; | ||
if (typeof body === 'object') { | ||
if (expectation.hasProperty in body) { | ||
result.ok = true; | ||
result.got = `${body[expectation.hasProperty]}`; | ||
return result; | ||
} else { | ||
result.got = `response body has no ${expectation.hasProperty} property`; | ||
return result; | ||
} | ||
} else { | ||
result.got = `response body is not an object`; | ||
return result; | ||
} | ||
} | ||
function prepend(text, str) { | ||
return text | ||
.split('\n') | ||
.map(function(line) { | ||
return str + line; | ||
}) | ||
.join('\n'); | ||
} |
{ | ||
"name": "artillery-plugin-expect", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Expectations and assertions for HTTP", | ||
@@ -14,4 +14,15 @@ "main": "index.js", | ||
"datadog-metrics": "^0.8.1", | ||
"debug": "^3.1.0" | ||
"debug": "^3.1.0", | ||
"lodash": "^4.17.10" | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "^7.0.0", | ||
"@commitlint/config-conventional": "^7.0.1", | ||
"husky": "^1.0.0-rc.13" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"commit-msg": "commitlint -e" | ||
} | ||
} | ||
} |
# artillery-plugin-expect | ||
## Functional API testing with Artillery | ||
Add expectations to your HTTP scenarios for functional API testing with Artillery. | ||
🐞 Please report issues over at [https://github.com/shoreditch-ops/artillery/issues](https://github.com/shoreditch-ops/artillery/issues) | ||
## Usage | ||
@@ -30,2 +34,5 @@ | ||
url: "/pets" | ||
capture: | ||
- json: "$.name" | ||
as: name | ||
expect: | ||
@@ -35,6 +42,49 @@ - statusCode: 200 | ||
- hasProperty: results | ||
- equals: | ||
- "Tiki" | ||
- "{{ name }}" | ||
``` | ||
## Expectations | ||
### `statusCode` | ||
Check that the response status code equals the code given. | ||
``` | ||
expect: | ||
- statusCode: 201 | ||
``` | ||
### `contentType` | ||
Check the value of [`Content-Type`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) header. | ||
### `hasProperty` | ||
When the response is JSON, check that the response object has a property. Same as [`lodash#has`](https://lodash.com/docs/#has). | ||
``` | ||
expect: | ||
- hasProperty: 'data[0].id' | ||
``` | ||
### `equals` | ||
Check that two or more values are the same. **NOTE** only primitive values (e.g. booleans, strings and numbers) are currently supported. | ||
``` | ||
- get: | ||
url: "/pets/f037ed9a" | ||
capture: | ||
- json: "$.species" | ||
as: species | ||
expect: | ||
- equals: | ||
- "{{ species }}" | ||
- "dog" | ||
``` | ||
## License | ||
MPL 2.0 |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Copyleft License
License(Experimental) Copyleft license information was found.
Found 1 instance in 1 package
Non-permissive License
License(Experimental) A license not known to be considered permissive was found.
Found 1 instance in 1 package
28782
236.83%8
166.67%322
25.29%89
128.21%4
33.33%3
Infinity%3
200%70
-30%2
Infinity%+ Added