• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

raml-mocker: Raml-mocker 是基于 Raml 的 mock server,Raml 是 RESTfull API 描述语 ...

原作者: [db:作者] 来自: 网络 收藏 邀请

Raml-mocker

versionnode (scoped)Build Statuscodecov

Raml-mocker 是基于 Raml 的 mock server,Raml 是 RESTfull API 描述语言,同时支持自定义指令。raml-mocker 可以根据 raml 描述文档读取到 API 中的 uri 及 response 中的 example 继而生成 mock server。

在 2.0 版本中增加了 API 接口的测试,所以 Raml-mocker 不仅仅是 mock server,还是一个不错的 API 接口测试工具。

开始

初始化项目

git clone https://github.com/xbl/raml-mocker-starter.git raml-apicd raml-apigit remote rm origin

安装

yarn# ornpm install
启动 mock server
yarn start# ornpm start

console

命令行会输出 Mock Server 的地址,不熟悉 Nodejs 的同学可以参考这里,使用 Docker 启动。

注意:此地址是 API 接口的 host,需要请求接口完整路径才能返回正确数据。

验证一下

curl -i http://localhost:3000/api/v1/articles# orcurl -i http://localhost:3000/api/v1/articles/bbb

或者使用 Postman:

Postman

生成 API 可视化文档

yarn run build# ornpm run build

会在工程下面生成一个 api.html 文件,双击打开即可看到一个 html 文档,如图:

API 文档

此功能使用了raml2html

配置 .raml-config.json

{  "controller": "./controller",  "raml": "./raml",  "main": "api.raml",  "port": 3000,  "plugins": []}
  • controller: controller 目录路径,在高级篇中会有更详细说明
  • raml: raml 文件目录
  • main: raml 目录下的入口文件
  • port: mock server 服务端口号
  • plugins: 插件(可能会有变动

入门篇:Mock Server

在 ./raml/api 目录下创建 books 文件夹:

目录结构

在 books 文件夹中创建 books.raml 文件

get:  description: 图书列表  responses:    200:      body:        application/json:          type: object          example: !include ./books_200.json

在 books 文件夹中创建 books_200.json 文件

{  "code": 200,  "data": [    {      "id": 1,      "title": "books title",      "description": "books desccription1"    },    {      "id": 2,      "title": "books title",      "description": "books desccription2"    }  ]}

修改 ./raml/api.raml

#%RAML 1.0---title: hello demo APIbaseUri: /version: v1mediaType: application/json# 安全设置securitySchemes: !include ./securitySchemes.raml# 自定义资源 types,类似于资源模板,指定 type 可以减少代码,还可以覆盖模板resourceTypes: !include ./resourceTypes.raml# 相当于数据类型,可用于自动化测试作为验证条件types: !include ./types.raml#/api/v1:  /articles: !include ./api/articles/articles.raml  /products: !include ./api/products/products.raml  /login: !include ./api/users/login.raml  # 添加  /books: !include ./api/books/books.raml

请求时是将 /api/v1/books 与 host 拼接出来的 URL,/api/v1 可在文档 api.raml 中修改。

curl -X GET http://localhost:3000/api/v1/books

或者使用Postman:

Postman

高级篇:动态 Server

在 raml 文档中添加 (controller) 指令,即可添加动态的 Server,如:

/books:  type:    resourceList:  get:    description: 获取用户的书籍    (controller): user#getBook    responses:      200:        body:          type: song[]          example: !include ./books_200.json

在文档中 (controller) 表示 controller 目录下 user.js 中 getBook 函数。

controller/user.js

exports.getBook = (req, res, webApi) => {  console.log(webApi);  res.send('Hello World!');}

Raml-mocker 是在 expressjs 基础上进行开发,req、res 可以参考 express 文档。

如此,raml-mocker 提供了更多可扩展空间,我们甚至可以在 controller 中实现一定的逻辑判断。

API 自动化测试

在 1.1.0 中增加 API 测试,通过在 raml 文件中添加 response 数据格式描述,raml-runner 会发送请求,来验证 response 的数据格式是否符合预期。

runner

  1. 在 types 文件中编写商品 Type,描述了返回数据的类型,以及对象中字段验证:
Product:  type: object  properties:    productId:      type: string      minLength: 4      maxLength: 36      required: true    productName: string    description: string    price: number
  1. 在 API Raml 中添加 type 字段:
get:  description: 商品列表  queryParameters:    isStar:      description: 是否精选      type: boolean      required: false      example: true  responses:    200:      body:        # 这里描述的商品数组        type: Product[]        example: !include ./products_200.json/{productId}:  get:    description: 商品详情    (controller): product#getProductDetail    (uriParameters):      productId:        description: productId        example: aaaa    responses:      200:        body:          # type 这里描述的商品          type: Product          example: !include ./product_200.json
  1. 启动 Mock Server,并运行测试
# 启动 Mock Servernpm start# 运行 API 测试npm test

设置不同环境

运行测试时默认会测试 Mock Server的 response,设置不同的环境方式如下:

编辑 .raml-config.json 文件

{  "controller": "./controller",  "raml": "./raml",  "main": "api.raml",  "port": 3000,  "runner": {    "local": "http://localhost:3000",    "dev": "http://abc.com:3001"  }}

在 runner 添加不同的环境对应的 HOST,通过 SET NODE_ENV 来更改运行不同环境的测试。

cross-env NODE_ENV=dev raml-runner# 为了方便已经在模板项目中添加了 npm script,可自由更改npm run test:dev

前置条件

以上只能满足不需要登录的 API 测试,登录的接口则需要 优先 执行,然后再执行其他接口,此处为了简单增加了(runner) 指令:

/login    post:      description: 登录      body:        username:          description: 用户名          type: string          required: true          example: abc        password:          description: 密码          type: string          required: true          example: abc      (runner):      	# 注意:这里的相对路径是相对于工程目录,而不是当前文件。        after: ./runner/afterLogin.js      responses:        200:          body:            type: string            example: fdafda232432fdaxfda25dfa

解析 raml 文件会优先执行带有 (runner) 指令的接口,并在执行完成之后调用 after 对应的 js 文件。

afterLogin.js

module.exports = (axios, response) => {  axios.defaults.headers.common['Authorization'] = response.data;}

测试发请求使用的 axios 模块,所以这里会在函数参数中添加 axios 实例,以及执行 login 接口的 response 对象。通常,设置 Header 就可以满足登录所需要的大部分场景。

afterLogin.js 可返回 Promise 对象:

module.exports = (axios, response) => {  return new Promise((resolve, reject) => {    axios.defaults.headers.common['Authorization'] = response.data;    setTimeout(() => {      console.log('不仅设置了header,还吃了个饭,洗了个澡...');      resolve()    }, 3000);  });}

API 场景测试

在 2.0 中增加了 API 的场景测试,在目录中增加了 test 文件夹。

  1. 在 raml 中增加 description
get:	# 请保证 description 唯一  description: 商品列表  queryParameters:    isStar:      description: 是否精选      type: boolean      required: false      example: true    isOk:      description: 是否精选2      type: boolean      required: false      example: true  responses:    200:      body:        type: Product[]        example: !include ./products_200.json

注意: description 的字符串会在 loadApi 时使用,所以请保证唯一。

  1. 在 test 目录新增 article.spec.js
const assert = require('assert');const { loadApi } = require('@xbl/raml-mocker');it('从文章列表到文章详情', async () => {  // 根据 `文章列表` 的 description 找到 raml 描述的 API  const getList = loadApi('文章列表');  const { status, data: list } = await getList();  const articleId = list[0].articleId;  assert.equal(status, 200);  assert.equal(articleId, 'A00001');  const getDetail = loadApi('文章详情');  const { data: detail } = await getDetail({ id: articleId });  assert.equal(detail.title, '提升家里整体格调的小物件');});

测试框架集成了 Mocha,断言使用 Nodejs 自带的 Assert 模块,开发者可以选择自己喜欢的断言库。

运行测试:

npm run test:api

运行测试

API

loadApi(description: string): Function;// loadApi 接收一个字符串参数,返回一个函数anonymousFn (uriParameters, queryParameter, body): Promise<AxiosResponse>/** * uriParameters: { *  id: 1 *  ... * } * * queryParameter: { *  pageSize: 20 *  ... * } * * body 是 POST 的数据 */

AioseResponse 文档可参考这里

旧有项目如何使用 raml-mocker

HTTP Archive (HAR) 反向工程

2.0 新增的功能,帮助开发者和测试同学可以在旧有项目中快速使用 raml-mocker,并生成测试代码片段。请看视频

视频

通过 har 文件生成 raml

以 npm 为例:

har-convert -f ./www.npmjs.com.har -o ./raml/api.raml -filter www.npmjs.com

通过 har 文件生成测试片段

har-convert -f ./www.npmjs.com.har -o ./test/search.spec.js

可通过录制特定场景的请求可生成该场景的测试片段。

关于 har 可参考这里

Road Map

  • API 自动化测试
  • API 场景测试
  • 自动化增加前置条件,如:登录
  • 读取 HTTP Archive (HAR) format 反向工程
  • 多场景的契约测试
  • Mock Server 增加请求参数验证
  • baseUriParameters
  • 上传文件的处理

使用遇到问题?

使用中遇到任何问题,请给告诉我好吗?


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap