UNPKG

api-bdd-test

Version:

use the bdd(cucumber) to test the RESTfull API

217 lines (169 loc) 6.99 kB
# 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, ``` Feature: Standard API Test 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 Then The last status code should be not: 400 Then The last result should be: ---- id: 10 a: 13 ---- ``` the genernal Chinese api steps: * `[新创]建资源\\s*[::]?[((]?$identifier(?:[))]?\\s*[,,.。])?[的其]?(?:内容|结果)[为是]?\\n$object` * `[编修][辑改](?:id|ID|编号)[为是::]?$string的?资源\\s*'+res4DataRegEx` * `删[除掉](?:id|ID|编号)[为是::]?$string的?资源\\s*[::]?[((]?$identifier(?:[))]?\\s*[,,.。])?` * `检[查测]是否存在资源\\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 ### 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