Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/snowyu/api-bdd-test.js
Use the BDD(Cucumber) to test the RESTful API.
https://github.com/snowyu/api-bdd-test.js
api bdd cucumber testing yadda
Last synced: about 1 month ago
JSON representation
Use the BDD(Cucumber) to test the RESTful API.
- Host: GitHub
- URL: https://github.com/snowyu/api-bdd-test.js
- Owner: snowyu
- License: mit
- Created: 2017-01-20T13:37:25.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2018-03-07T05:34:16.000Z (over 6 years ago)
- Last Synced: 2024-09-30T08:01:23.541Z (about 2 months ago)
- Topics: api, bdd, cucumber, testing, yadda
- Language: CoffeeScript
- Homepage:
- Size: 54.7 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-MIT
Awesome Lists containing this project
README
# API BDD Test
Use the BDD(Cucumber) to test the RESTful API.
### Installation
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.
1. generate the `.api-bdd-test.json|.cson|.yml` 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.
The `language` is the default bdd language used in the specifications.
The `server` is the api server default url.
The `libs`, `steps` and `features` are the folders to store. the defauls is to
in the `test` folder.### Usage
* 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.
* tag with `@pending` before the scenario to stop the scenario.
* tag with `@before` before the scenario to turn the scenario to a before feature hook.
* tag with `@after` before the scenario to turn the scenario to a after feature hook.
* tag with `@beforeEach` before the scenario to turn the scenario to a before each scenario hook.
* tag with `@afterEach` before the scenario to turn the scenario to a after each scenario hook.
* tag with `@beforeStep` before the scenario to turn the before each step hook.
* tag with `@afterStep` 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/`
* the object is [cson format](https://github.com/bevry/cson)
* 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+results?\s+(?:should\s+)?(be|is|are|includes?)\n$object/`
* `/(?:last|prev(?:ious)?)\s+status\s*(?:code)?\\s*(?:should\\s+)?((?:be|is)(?:n't|\s+not)?)\s*[:]?\s*$integer/`
* keep the `result.body.id` 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"
And keep the result to "myres"
And expect the stored `myid` equal 10
And expect the stored `myid1` equal 10
And expect the stored `myid` is not equal 0
And expect the kept `myid` 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.
The `a.steps.js` script in the `steps` folder will be loaded for `a.feature`.
The `steps` script file extend name should be end with `[.-]step[s]?\\.(js|coffee)`The `libs` script(extend name should be end with`[.-](lib[s]?|dict[s]?)\.(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:
```js
//the `this` 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();
});
}
```## limits
* no back ref in regexp.
* no optional group on `$xxx` defininition. eg, `$string?` should be wrong.
* report the `<-- Undefined Step` error:
1. Duplication Regexp Step
2. Optional Group in the regexp step.## History
### V0.5.1
* [Broken] the `resNameRegEx`(Chinese) force use limiter to get the identifier.
### V 0.4.0
+ 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### V 0.3.0
+ referernce the variaible which stored by steps. use the "``" delimiter instead.
* it's an one line coffee-script code in this delimiter.
* `\`"#{myid}"\``## TODO