3loc 中文文档教程
3loc
一个简单但可定制的集成测试工具:
- Choose/write a test scenrio for your integration tests
- Writes our test fixtures into one or several CSV/YAML files
- Run the command and enjoy the results !
Principles
3loc 针对现有系统运行测试,发送输入和预期结果。 如果收到的结果不是预期的,它会抱怨。
它专注于 Http 服务、SOAP 和 REST。
测试场景基本上是 JavaScript 文件,包含一系列操作和期望。 您肯定需要多次运行相同的场景,测试数据略有变化:发送到测试 WebService 的主体,或预期的状态代码。
我们称它们为夹具,您可以将它们外部化到专用文件中(支持多种格式)。 事实上,fixture 文件是使用 3loc 的入口点,因为它定义了使用的场景文件。
Installation
3loc 建立在 Node.js 4+ 之上。 您需要将其安装在计算机上才能使用。
由于 3loc 使用 libXML.js,这需要一些 C++ 编译,因此您还需要一个 C++ 编译器 (例如 gcc 或 Visual Studio Community Edition)。
安装 Node 和 C++ 编译器后,运行以下命令进行安装
npm install --global 3loc
(然后喝杯咖啡)
Execution
从命令行或终端运行
run path/to/fixture.yml
CLI 选项已记录:
run
Providing test fixtures
测试装置用于为场景文件添加一些动态性. 这是一个示例:
return () =>
run(request({
url: 'http://api.wolframalpha.com/v2/query?input=<$ input $>&appid=<$ appId $>&includepodid=Result'
})).
then(expectStatusCode(<$ status $>)).
then(expectXPathToEqual('//pod[id="Result"]//plaintext', '<$ sum $>'));
它对 Wolfram API 进行 Http 调用,获取并解析 XML内容, 检查接收到的状态代码并使用 XPath 表达式检查结果。
看到那些 <$ $>
占位符(input
、sum
…)了吗? 它们被提供的测试数据所取代。
With YAML
YAML 可能是编写固定装置的最佳选择。 这是上述场景的 YAML 文件:
scenario: ./path_to/my-scenario.scn
appId: HLJL66-4W3HPXYYP8
tests:
- name: nominal case
input: 3%2B4
sum: 7
status: 200
- name: handling nulls
input: 3%2Bnull
sum: 3
status: 200
scenario
是场景文件的路径(必需)。
tests
是一个对象数组,每个对象都被视为给定测试的特定装置。 如果 3loc 在 tests
中找到两个对象,它将使用给定的对象运行场景两次。
在 tests
和根级别中,您可以放置任何内容,从简单的字符串/布尔值到复杂的数组/映射结构。
内容将在场景文件中使用:
input
,sum
andstatus
are defined at test levelsappId
is common to all tests (but can be overloaded per test)
如果您在测试级别指定一个名称
,它将在最终报告中使用。 否则,将生成一个带有测试编号的名称。
您不能为每个测试使用不同的场景。 如果您愿意,可以编写不同的灯具文件。
最后但同样重要的是,YAML 文件可以包含其他 YAML 文件,使用以下宏:
config: !!inc/file configuration.yaml
!!inc/file
执行同步读取给定路径(相对于包含文件)并被其内容替换。
With CSV
不如 YAML 灵活,它适用于一些数据基本平坦、不共享大量数据以及需要不同场景的情况。 上述场景的 CSV fixture 是:
scenario;name;appId;input;sum;status
./path_to/my-scenario.scn;HLJL66-4W3HPXYYP8;"nominal case";3%2B4;7;200
./path_to/my-scenario.scn;HLJL66-4W3HPXYYP8;"handling nulls";3%2Bnull;3;200
每一行将执行不同的测试。 scenario
列包含场景文件的路径(必需)。
任何其他列包含测试内部使用的数据。 如果您在列名中加上点,则数据替换将是树状的。 例如,对于名为 host.url
的列,替换将是 request({host: '<$ host.url $>'})
数据是包含 url
属性的 host
对象。
如果您指定一个 name
列,它将在最终报告中使用。 否则,将生成一个带有测试编号的名称。
您不能在不同的测试之间共享数据。 为此,请使用 YAML fixture 文件。
Common considerations
无论使用何种格式,以下注意事项始终适用:
scenario
path is always relative to the fixture location (you can provide absolute path as well)scenario
can directly contains the JavaScript code (only suit really tiny scenarii)- Tests are executed serially: the program bails at first error
- Test execution folder is always the folder containing the scenario file. Data used as path (
load
action for example) are relative to that folder - When providing scenario content directly, the execution folder is the one containing the fixture file
Logging
默认情况下,3loc 并不是很冗长。 但如果您配置日志记录,它可能会更繁琐:只需将 logging.properties
文件放在执行文件夹中。
文件语法是经典的 INI 文件,其中类别是记录器名称,值允许自定义其参数
[my-logger-1]
level=error
[my-logger-2]
level=debug
: conf 被定期监视,因此您可以在 3loc 运行时更改您的文件。
按照惯例,每个动作/期望都使用自己的记录器,因此您可以进行细粒度的调整。
Scenario authoring
场景文件是 JavaScript 文件,使用 Nunjucks 模板语言进行模板化。
显然,它们必须是格式良好的 JavaScript 在模板编译之后。
Templating
为了提高可读性,默认的 Nunjucks 分隔符已被更改:
- blockStart: '<%'
- blockEnd: '%>'
- variableStart: '<$'
- variableEnd: '$>'
- commentStart: '<#'
- commentEnd: '#>'
请注意,占位符是类型感知的(这是对 Nunjuck 行为的改进)。 例如这个场景:
load(<$ file $>)
只有当你在夹具文件中提供一个字符串值时它才会编译。
布尔和数字类型保存在模板中, 字符串固定装置自动用双引号引起来, 数组和对象被序列化为 JSON。
lodash v4.0.1 中的所有方法也可用作 Nunjuck 过滤器:
run(request(<$ endpoint | pick('url', 'headers') $>)).
then(expectContentToInclude(<$ filename | camelCase $>))
第一个方法参数始终是过滤后的值,您可以添加额外的参数. 它严格等同于写: var _ = require('lodash');
run(request(_.pick(<$ endpoint $>, 'url', 'headers'))).
then(expectContentToInclude(_.camelCase(<$ filename $>)))
您还可以对所有内容进行硬编码,在这种情况下,fixtures 文件只需要为每个测试指定场景路径和名称。
Returning the proper thing
您的场景文件必须以返回结束:
- A Promise. ex:
return Promise.resolve(18);
- A synchronous function. ex
return function() { return 18; };
- An asynchronous function. ex
return function(done) { require('fs').readFile('myfile.txt', done); };
(asynchronous functions differs from synchronous function because they declare a single argument)
最好的办法是返回 run() 或 runSerial()< 的结果/a> 行动。
It's just JavaScript
它是在 Node.js 上执行的。 这意味着 Node 的 API 可用(通过使用 require()
函数), 以及 3loc 自己的依赖项(lodash、moment、< a href="http://chaijs.com/">chai, joi ...)
当你的测试运行时在 Node.js 上,您可以使用 4.2 版支持的 ES6 功能 (箭头函数、promises、字符串插值、类……)。
Available actions
所有操作都是脚本文件中自动可用的 JavaScript 函数(不需要任何其他要求)。 它们可以在 Promises 中组合,并且旨在以这种方式使用。
不要不处理 promise 拒绝,除非您的场景需要在错误发生后继续测试内容。 名义上的情况是让错误冒泡并停止当前执行的测试。
listen
启动 HTTP 服务器以侦听给定的 url。 可以配置可接受的方法,具有响应主体和标头。
如果传递的是 JSON 主体,则将默认响应内容类型设置为 application/json
。 如果传递 libXML.js 文档主体,请将默认响应内容类型设置为 application/xml
。 如果需要,您仍然可以覆盖响应内容类型。
如果 body 作为函数给出,它必须返回一个已实现的承诺 使用包含 content
属性的对象。
请求体将被自动解析(使用请求内容类型)为 libXML.js 文件或 JSON 对象以供进一步处理。 否则,请求正文作为字符串传递。
listen({
port: 4000,
url: '/my-api',
method: 'POST',
body: '{"msg": "response sent"}',
headers: {
'content-type': 'application/json',
'x-custom': 'custom'
},
code: 200
}).then(...)
- opt.port {Number} - absolute or relative path to read file
- opt.url {String} - acceptable url to listen to
- opt.method = GET {String} - acceptable Http method
- opt.body = '' {String|Object|Document|Function} - response sent to incoming request
- opt.headers = {} {Object} - response headers sent to incoming request
- opt.code = 200 {Number} - status code sent to incoming request
- returns {Function} function usable in promises chain. Takes as first parameter an object. Returns a promise fulfilled with the same object, containing
- content {String} - response body received (might be parsed in JSON/XML)
- headers {Object} - response headers
记录器名称:act:listen
load
将文件内容作为字符串加载。 通常用于读取请求/响应主体、XSD 文件……
load('./path_to/file.txt', 'ascii').then(...)
- path {String} - absolute or relative path to read file
- encoding = utf8 {String} - encoding used to read the file
- returns {Function} function that loads the file when invoked. Takes as first parameter an object. Returns a promise fulfilled with the same object, containing
- content {String} - response body received (might be parsed in JSON/XML)
- path {Object} - absolute or relative path to read file
记录器名称:act:load
render
使用给定数据呈现 Nunjucks 模板。 请参阅 Nunjucks 模板语言, 带有特定的分隔符(为了场景文件的可读性)
- blockStart: '<%',
- blockEnd: '%>',
- variableStart: '<$',
- variableEnd: '$>',
- commentStart: '<#',
- commentEnd: '#>'
render('Hello <$ name $> !', {name: 'James'}).then(...)
如果内容作为函数给出,它必须返回一个已实现的承诺 对象包含 content
和 path
属性。
- content {String|Function} - template rendered
- data = {} {Object} - data used for rendering
- returns {Function} function usable in promises chain. Takes as first parameter an object Returns a promise fulfilled with the same object, containing
- content {String} - the rendered template
记录器名称:act:render
request
在给定的 url 上发出 HTTP(s) 请求。 HTTP 方法、标头和跟随重定向的能力是可配置的。
如果传递的是 JSON 正文,请将默认请求内容类型设置为“application/json”。 如果传递 libXML.js 文档正文,请将默认请求内容类型设置为“application/xml”。 如果需要,您仍然可以覆盖请求内容类型。
请求体将被自动解析(使用请求内容类型)为 libXML.js 文件或 JSON 对象以供进一步处理。 否则,请求正文作为字符串传递。
request({
url: 'http://localhost:8080/my-api',
method: 'PUT',
body: '{"msg": "request sent"}',
headers: {
'content-type': 'application/json',
'x-custom': 'custom'
},
followRedirect: true
}).then(...)
如果您需要传递查询参数,请使用url对其进行编码。
如果 body 作为函数给出,它必须返回一个已实现的承诺 使用包含 content
属性的对象。
- opt.url {String} - full url (protocol, host, port, path) requested
- opt.method = GET {String} - method used
- opt.body = '' {String|Object|Document} - body sent (only when doing POST and PUT)
- opt.headers = {} {Object} - request headers
- opt.followRedirect = false {Boolean} - automatically follows redirection
- returns {Function} function usable in promises chain. Takes as first parameter an object. Returns a promise fulfilled with the same object, containing
- content {String} - response body received (might be parsed in JSON/XML)
- headers {Object} - response headers
- code {Number} - http status code
记录器名称:act:request
run
使用提供的数据同步运行给定函数,并包装到 承诺下一步行动和期望。 开始新场景时的必备品。
run(request({url: 'http://somewhere.com/'}))
fs {Function} - 执行的函数
data = {} {Object} - 作为函数参数给出的可选数据
< strong>返回 {Promise} 用函数结果实现
记录器名称:act:run
runSerial
连续运行函数数组, 将任务 N 的结果作为任务 N+1 的参数传递。
请注意,您必须传递数组函数。 不要给出承诺,否则它们将一次性全部启动。
runSerial([
() => Promise.resolve(1),
p => Promise.resolve(p + 1)
].then(result => ...) // result === 2
- tasks {Array
} - tasks to be executed - returns {Function} that when invoked, will return promise fulfilled with the latest task's result
记录器名称:act:serial
Expectations
所有操作都是在场景文件中自动可用的 JavaScript 函数(无需任何其他要求)。 它们可以在 Promises 中组合,并且旨在以这种方式使用。
不要不处理 promise 拒绝,除非您的场景需要在错误发生后继续测试内容。 名义上的情况是让错误冒泡并停止当前执行的测试。
expectContentToInclude
检查接收到的内容是否包含给定元素, 或匹配给定的模式。
run(load('my-file.txt')).
then(expectcontentToInclude('Hi !'))
- element {String|Regex} - expected element or matching pattern
- returns {Function} function usable in promises chain Takes as first parameter an object containing
- content {Object} - checked content
- returns {Promise} fulfilled with the same object
记录器名称:expect:content
expectStatusCode
检查是否已收到给定的状态代码。
run(request({'http://somewhere.com/api'})).
then(expectStatusCode(404))
- code {Number} - expected value
- returns {Function} function usable in promises chain Takes as first parameter an object containing
- code {Object} - checked code value
- returns {Promise} fulfilled with the same object
记录器名称:expect:status
expectToMatchXsd
根据给定的 XSD 内容验证传入的内容。 在内部使用 libXML.js。 XSD 和 XML 内容可以作为纯字符串或作为 libXML.js 的文档对象传递
如果 xsd 作为函数给出,它必须返回一个已实现的承诺 使用包含 content
属性的对象。
run(request({'http://somewhere.com/api'})).
then(expectToMatchXsd(load('schema.xsd')))
- xsd {String|Object|Function} - xsd content used for validation
- returns {Function} function usable in promises chain. Takes as first parameter an object containing
- content {String|Object} - xml content validated
- returns {Promise} fulfilled with the same object, where content has been enriched as a libXML.js's Document
记录器名称:expect:xsd
3loc
A simple-yet-customizable integration test tool:
- Choose/write a test scenrio for your integration tests
- Writes our test fixtures into one or several CSV/YAML files
- Run the command and enjoy the results !
Principles
3loc runs tests against existing system, sending input and expecting results. If received results are not the one expected, it will complain.
It's focused on Http services, SOAP and REST.
Test scenarii are basically JavaScript files, containing a serie of actions and expectations. You will surely need to run the same scenario multiple times, with slight changes in the test data: body sent to the tested WebService, or expected status code.
We called them fixtures, and you can externalize them in a dedicated file (multiple format are supported). In fact, the fixture file is the entry point when using 3loc, as it defined the scenario file used.
Installation
3loc is built upon Node.js 4+. You'll need to install it on your computer to use it.
As 3loc uses libXML.js, which requires some C++ compilation, you'll also need a C++ compiler (gcc or Visual Studio Community Edition for example).
Once you have installed Node and a C++ compiler, run the following command to install
npm install --global 3loc
(then have a cup of coffee)
Execution
From a command line or a terminal, run
run path/to/fixture.yml
CLI options are documented:
run
Providing test fixtures
Test fixtures are used to add some dynamicity to your scenario files. This is an example:
return () =>
run(request({
url: 'http://api.wolframalpha.com/v2/query?input=<$ input $>&appid=<$ appId $>&includepodid=Result'
})).
then(expectStatusCode(<$ status $>)).
then(expectXPathToEqual('//pod[id="Result"]//plaintext', '<$ sum $>'));
It makes an Http call to the Wolfram API, get and parse the XML content, checks the received status code and check the result with an XPath expression.
See thoses <$ $>
placeholders (input
, sum
…) ? they are replaced with the provided test data.
With YAML
YAML is probably the best choice to write your fixtures. Here is the YAML file for the above scenario:
scenario: ./path_to/my-scenario.scn
appId: HLJL66-4W3HPXYYP8
tests:
- name: nominal case
input: 3%2B4
sum: 7
status: 200
- name: handling nulls
input: 3%2Bnull
sum: 3
status: 200
scenario
is the path the the scenario file (required).
tests
is an array of objects, each considered as the specific fixtures of a given test. If 3loc find two objects in tests
, it will runs the scenario twice, using the given objects.
Inside tests
and in root level, you can put anything, from simple string/boolean to complex array/map structures.
The content will be used inside the scenario file:
input
,sum
andstatus
are defined at test levelsappId
is common to all tests (but can be overloaded per test)
If you specify a name
at test level, it will be used in final report. Otherwise, a name with test number will be generated.
You can't use different scenarii for each test. If you whish, write different fixtures files.
Last but not least, a YAML file can include other YAML files, using the following macro:
config: !!inc/file configuration.yaml
The !!inc/file
performs a synchronous read of the given path (relative to the including file) and is replaced by its content.
With CSV
Less flexible than YAML, it suits some cases where data is mearly flat, does not share a lot of data, and when you want diffent scenarii. The CSV fixtures for the above scenario is:
scenario;name;appId;input;sum;status
./path_to/my-scenario.scn;HLJL66-4W3HPXYYP8;"nominal case";3%2B4;7;200
./path_to/my-scenario.scn;HLJL66-4W3HPXYYP8;"handling nulls";3%2Bnull;3;200
Each line will execute a different test. scenario
column contains the path the the scenario file (required).
Any other column contains data used inside test. If you put dots in the column name, the data replace will be treeish. For example, with a column named host.url
, the replacement will be request({host: '<$ host.url $>'})
and the data is an host
object containing an url
property.
If you specify a name
column, it will be used in final report. Otherwise, a name with test number will be generated.
You can't share data among different tests. For that, please use a YAML fixture file.
Common considerations
Whatever the format used, the following considerations always apply:
scenario
path is always relative to the fixture location (you can provide absolute path as well)scenario
can directly contains the JavaScript code (only suit really tiny scenarii)- Tests are executed serially: the program bails at first error
- Test execution folder is always the folder containing the scenario file. Data used as path (
load
action for example) are relative to that folder - When providing scenario content directly, the execution folder is the one containing the fixture file
Logging
By default, 3loc is not really verbose. But it can be more chatty if you configure logging: just put a logging.properties
file in the execution folder.
The file syntax is a classical INI file where the category is the logger name, and the values allows to customize its parameter:
[my-logger-1]
level=error
[my-logger-2]
level=debug
The conf is regularly watched so you can change you file while 3loc is running.
By convention, each actions/expectation uses its own logger, so you can have a fine-grained tunning.
Scenario authoring
Scenario files are JavaScript files, templated with Nunjucks template language.
Obviously they must be well-formed JavaScript after the template compilation.
Templating
To improve readability, the default Nunjucks's delimiter have been changed:
- blockStart: '<%'
- blockEnd: '%>'
- variableStart: '<$'
- variableEnd: '$>'
- commentStart: '<#'
- commentEnd: '#>'
Be warned that placeholders are type-aware (which is an improvment of Nunjuck behavior). For example this scenario:
load(<$ file $>)
It will compiles only if you provides a string value in the fixture file.
Boolean and number types are kepts within templates, strings fixtures are automatically enclosed in double quotes, arrays and objects are serialized into JSON.
All methods from lodash v4.0.1 are also available as Nunjuck filters:
run(request(<$ endpoint | pick('url', 'headers') $>)).
then(expectContentToInclude(<$ filename | camelCase $>))
The first method parameter is always the filtered values, and you can add extra parameters. It's strictly equivalent to write: var _ = require('lodash');
run(request(_.pick(<$ endpoint $>, 'url', 'headers'))).
then(expectContentToInclude(_.camelCase(<$ filename $>)))
You can also hardcode everything, and in that case, the fixtures file only needs to specify scenario path and a name for each tests.
Returning the proper thing
Your scenario file must ends by returning either:
- A Promise. ex:
return Promise.resolve(18);
- A synchronous function. ex
return function() { return 18; };
- An asynchronous function. ex
return function(done) { require('fs').readFile('myfile.txt', done); };
(asynchronous functions differs from synchronous function because they declare a single argument)
The best thing to do is to return the result of run() or runSerial() actions.
It's just JavaScript
And it's executed on Node.js. That means that Node's API are available (through the use of require()
function), as well as 3loc own dependencies (lodash, moment, chai, joi…)
As your tests are run on Node.js, you can use the ES6 features supported from version 4.2 (arrow functions, promises, string interpolation, classes…).
Available actions
All actions are JavaScript functions automatically available within scenario file (no need to require anything else). They are composable within Promises, and are intended to be used that way.
Do NOT handle promise rejections, unless your scenario needs to keep testing stuff after an error. The nominal case is to let errors bubnle an stop the current executed test.
listen
Starts an HTTP server to listen a given url. Acceptable method can be configured, has well as response body and headers.
If a JSON body is passed, set default response content-type to application/json
. If a libXML.js Document body is pased, set default response content-type to application/xml
. You can still override the response content-type if needed.
If body is given as a function, it must return a promise fulfilled with an object including a content
property.
Request body will be automatically parsed (using the request content-type) to libXML.js Document or to JSON object for further processing. Otherwise, the request body is passed as a string.
listen({
port: 4000,
url: '/my-api',
method: 'POST',
body: '{"msg": "response sent"}',
headers: {
'content-type': 'application/json',
'x-custom': 'custom'
},
code: 200
}).then(...)
- opt.port {Number} - absolute or relative path to read file
- opt.url {String} - acceptable url to listen to
- opt.method = GET {String} - acceptable Http method
- opt.body = '' {String|Object|Document|Function} - response sent to incoming request
- opt.headers = {} {Object} - response headers sent to incoming request
- opt.code = 200 {Number} - status code sent to incoming request
- returns {Function} function usable in promises chain. Takes as first parameter an object. Returns a promise fulfilled with the same object, containing
- content {String} - response body received (might be parsed in JSON/XML)
- headers {Object} - response headers
Logger name: act:listen
load
Loads file content as a string. Typically used to read request/response bodies, XSD files…
load('./path_to/file.txt', 'ascii').then(...)
- path {String} - absolute or relative path to read file
- encoding = utf8 {String} - encoding used to read the file
- returns {Function} function that loads the file when invoked. Takes as first parameter an object. Returns a promise fulfilled with the same object, containing
- content {String} - response body received (might be parsed in JSON/XML)
- path {Object} - absolute or relative path to read file
Logger name: act:load
render
Renders Nunjucks template with given data. See Nunjucks templating language, with the specific delimiters (for readability in scenarii files)
- blockStart: '<%',
- blockEnd: '%>',
- variableStart: '<$',
- variableEnd: '$>',
- commentStart: '<#',
- commentEnd: '#>'
render('Hello <$ name $> !', {name: 'James'}).then(...)
If content is given as a function, it must return a promise fulfilled with an object including a content
and path
properties.
- content {String|Function} - template rendered
- data = {} {Object} - data used for rendering
- returns {Function} function usable in promises chain. Takes as first parameter an object Returns a promise fulfilled with the same object, containing
- content {String} - the rendered template
Logger name: act:render
request
Makes an HTTP(s) request on a given url. The HTTP method, the headers and the ability to follow redirections are configurable.
If a JSON body is passed, set default request content-type to 'application/json'. If a libXML.js Document body is pased, set default request content-type to 'application/xml'. You can still override the request content-type if needed.
Request body will be automatically parsed (using the request content-type) to libXML.js Document or to JSON object for further processing. Otherwise, the request body is passed as a string.
request({
url: 'http://localhost:8080/my-api',
method: 'PUT',
body: '{"msg": "request sent"}',
headers: {
'content-type': 'application/json',
'x-custom': 'custom'
},
followRedirect: true
}).then(...)
If you need to pass query parameters, please encode them with the url.
If body is given as a function, it must return a promise fulfilled with an object including a content
property.
- opt.url {String} - full url (protocol, host, port, path) requested
- opt.method = GET {String} - method used
- opt.body = '' {String|Object|Document} - body sent (only when doing POST and PUT)
- opt.headers = {} {Object} - request headers
- opt.followRedirect = false {Boolean} - automatically follows redirection
- returns {Function} function usable in promises chain. Takes as first parameter an object. Returns a promise fulfilled with the same object, containing
- content {String} - response body received (might be parsed in JSON/XML)
- headers {Object} - response headers
- code {Number} - http status code
Logger name: act:request
run
Runs synchronously a given function, with provided data, and wrap to Promise for next actions and expectations. A must-have when starting a new scenario.
run(request({url: 'http://somewhere.com/'}))
fs {Function} - function executed
data = {} {Object} - optionnal data given as function argument
returns {Promise} fulfilled with the function result
Logger name: act:run
runSerial
Runs an array of function serially, passing result of task N as parameter of task N+1.
Beware that you must pass an array functions. Don't give promises, or they will be started all in once.
runSerial([
() => Promise.resolve(1),
p => Promise.resolve(p + 1)
].then(result => ...) // result === 2
- tasks {Array
} - tasks to be executed - returns {Function} that when invoked, will return promise fulfilled with the latest task's result
Logger name: act:serial
Expectations
All actions are JavaScript functions automatically available within scenario file (no need to require anything else). They are composable within Promises, and are intended to be used that way.
Do NOT handle promise rejections, unless your scenario needs to keep testing stuff after an error. The nominal case is to let errors bubnle an stop the current executed test.
expectContentToInclude
Checks that received content includes the given element, or matches the given pattern.
run(load('my-file.txt')).
then(expectcontentToInclude('Hi !'))
- element {String|Regex} - expected element or matching pattern
- returns {Function} function usable in promises chain Takes as first parameter an object containing
- content {Object} - checked content
- returns {Promise} fulfilled with the same object
Logger name: expect:content
expectStatusCode
Checks that a given status code has been received.
run(request({'http://somewhere.com/api'})).
then(expectStatusCode(404))
- code {Number} - expected value
- returns {Function} function usable in promises chain Takes as first parameter an object containing
- code {Object} - checked code value
- returns {Promise} fulfilled with the same object
Logger name: expect:status
expectToMatchXsd
Validates incoming content against a given XSD content. Use libXML.js internally. XSD and XML content can be passed as plain string, or as libXML.js's Document objects
If xsd is given as a function, it must return a promise fulfilled with an object including a content
property.
run(request({'http://somewhere.com/api'})).
then(expectToMatchXsd(load('schema.xsd')))
- xsd {String|Object|Function} - xsd content used for validation
- returns {Function} function usable in promises chain. Takes as first parameter an object containing
- content {String|Object} - xml content validated
- returns {Promise} fulfilled with the same object, where content has been enriched as a libXML.js's Document
Logger name: expect:xsd