use the bdd(cucumber) to test the RESTfull API
npm install api-bdd-testUse the BDD(Cucumber) to test the RESTful API.
1. Install in your project:
npm install --save-dev api-bdd-test mocha chai supertest loopback-supertest
1. mkdir test in your project root folder
1. generate the mocha.opts file in the test folder:
```
--timeout 10000
--ui spec
--growl
--colors
node_modules/api-bdd-test/index.js
* Or run mocha --ui spec node_modules/api-bdd-test/index.js directly..api-bdd-test.json|.cson|.yml
1. generate the in the root folder or test folder:
`yaml`
language: English
server: "http://localhost:3000"
root: "/api"
libs: "./libs"
steps: "./steps"
features: "./features"
The feature specifications in the features folder for reading and testing.language
The is the default bdd language used in the specifications.server
The is the api server default url.libs
The , steps and features are the folders to store. the defauls is totest
in the folder.
* test
* ./features
* a.feature
* ./steps
* a.steps.js
* b-step.js
* ./libs
* some.lib.js
* some.dict.js
#### features
* tag with @only before the scenario to execute the scenario only.@pending
* tag with before the scenario to stop the scenario.@before
* tag with before the scenario to turn the scenario to a before feature hook.@after
* tag with before the scenario to turn the scenario to a after feature hook.@beforeEach
* tag with before the scenario to turn the scenario to a before each scenario hook.@afterEach
* tag with before the scenario to turn the scenario to a after each scenario hook.@beforeStep
* tag with before the scenario to turn the before each step hook.@afterStep
* tag with before the scenario to turn the after each step hook.
`cucumber`
@only
Scenario Calc two value
language supports with:
* File name postfix: a.english.feature
* first line of the file: # language: English
the server, root/app, resource could be setting in .api-bdd-test.json|.cson|.yml file.
Or as the annotations in a feature file.
the genernal api steps:
* /(GET|HEAD|DEL(?:ETE)?)\s+$string//(GET|HEAD|DEL(?:ETE)?|POST|PATCH|PUT)\s+$string[:]\n$object/
* /(?:last|prev(?:ious)?)\\s+results?\s+(?:should\s+)?(be|is|are|includes?)\n$object/
* the object is cson format
* data: send to
* heads:
* type: accepting the canonicalized MIME type name complete with type/subtype, or simply the extension name such as "xml", "json", "png", etc, defaults to 'json'
* queries:
* fields:
* accepts:
* attachments:
* explain to see http://visionmedia.github.io/superagent/
* /(?:last|prev(?:ious)?)\s+status\s(?:code)?\\s(?:should\\s+)?((?:be|is)(?:n't|\s+not)?)\s[:]?\s*$integer/
result.body.id
* keep the to 'myvar'
eg,
`cucumber
Feature: Standard API Test
@before
Scenario: empty data before feature running
Given DELETE "bottle"
Scenario: POST and Get result
# POST 'http://127.0.0.1:3000/api/bottle'
# with data
#
Given POST "bottle":
----
type: 'json'
data:
id: 10
a: 13
----
Then The last status code should be: 200
And The last status code should be not: 400
And The last result should be:
----
id: 10
a: 13
----
And keep the result of "body.id" to "myid"
And keep the result.body.id to "myid1"myid
And keep the result to "myres"
And expect the stored equal 10myid1
And expect the stored equal 10myid
And expect the stored is not equal 0myid
And expect the kept least 1`
the genernal Chinese api steps:
* 新建资源:"resource",其内容为\n$object编辑(ID|编号)是:"the-id"的资源:"resource",其内容为\n$object
* 删除(ID|编号)是:"the-id"的资源:"resource"
* 检[查测]是否存在资源\\s[::]?[(( ]$identifier(?:[)) ]\\s[,,.。])?\\s[::]?$string
/上次[的]?(?:状态[码]?|status)[为是::]\s$identifier/
/上次[的]?(?:结果|body)([为是::]|包[括含][::]?)\s\n$object/
(?:获[取得]|取[得]?)(?:id|ID|编号)[为是::]?$string的?资源\\s[::]?[((]?$identifier(?:[))]?\\s*[,,.。])?[的其]?(?:内容|结果)[为是]?\\n$object
(?:获[取得]|取得?)资源\\s[::]?[((]?$identifier(?:[))]?\\s[,,.。])?\\s[::]?$string
([不]?会?存在|没有?|有)(?:id|ID|编号)[为是::]?$string的?资源\\s[::]?[((]?$identifier(?:[))]?\\s*[,,.。])?
/登[录陆]\s用户[::]\s$string\s[,,]\s密码[::]\s$string/
/注销用户|退出系统/
* /(?:记[住下忆]?|保[存留])结果的(?:属性)?$string到[::]?$string/
* 记住结果到"myvar"
* 保存的"mvar"等于xxx
* /(不?存在)(?:记[住下忆]?|保[存留]的)?\s$string$/
列[出举]资源\\s[::]?[(( ]$identifier(?:[)) ]\\s*[,,.。])?
[搜查][索询找]资源\\s'+resNameRegEx+'按?(?:指定|如下)?(?:条件|设置)[::]?$object
`
* 记住result.body[0].id到"myvar"`获得id为"id",过滤条件为"xxx"的资源: bottle
*
#### steps and libs
The all scripts in the libs folder will be loaded.a.steps.js
The script in the steps folder will be loaded for a.feature.steps
The script file extend name should be end with [.-]step[s]?\\.(js|coffee)
The libs script(extend name should be end with.-\.(js|coffee)) should be like this:
`js
var Dictionary = Yadda.Dictionary;
var converters = Yadda.converters;
module.exports = function(dictionary){
dictionary
.define('integer', /(\d+)/, converters.integer);
this
.define('Expect $integer to be an integer', function(i, next) {
assert.equal(typeof i, 'number');
assert(i % 1 === 0);
next();
});
}
`
The steps script(file name should be #{featureName}(.#{lang})?.step[s]?.(js|coffee)) should be like this:
`jsthis
//the is the Yadda.Library() (bind to current language)`
//the dict is the Yadda.Dictionary()
module.exports = function(dict){
this.given("$integer green bottles are standing on the wall", function(number_of_bottles) {
wall = new Wall(number_of_bottles);
wall.printStatus();
})
.when("$integer green bottle accidentally falls", function(number_of_falling_bottles) {
wall.fall(number_of_falling_bottles);
console.log("%s bottle falls", number_of_falling_bottles);
})
.then("there are $integer green bottles standing on the wall", function(number_of_bottles) {
assert.equal(number_of_bottles, wall.bottles);
wall.printStatus();
});
}
* no back ref in regexp.
* no optional group on $xxx defininition. eg, $string? should be wrong.<-- Undefined Step
* report the error:
1. Duplication Regexp Step
2. Optional Group in the regexp step.
* [Broken] the resNameRegEx(Chinese) force use limiter to get the identifier.
+ Add Special Scenarios
* add the before/after annotations for feature hook
* add the beforeEach/afterEach annotations for Scenario hook
+ add the beforeStep/afterStep annotations for step hook
+ referernce the variaible which stored by steps. use the "" delimiter instead.\
* it's an one line coffee-script code in this delimiter.
* "#{myid}"\`