成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Aest 功能強(qiáng)大的NodeJS Restful 接口測(cè)試工具

sihai / 853人閱讀

1. Aest

項(xiàng)目地址:https://github.com/wangduandu...

功能強(qiáng)大的REST接口測(cè)試工具, Power By Jest, axios, superstruct, mustache, lodash

2. 特點(diǎn)

非常簡(jiǎn)單: 大部分工作量在于寫(xiě)配置文件

請(qǐng)求模板: 可以在配置文件中加入運(yùn)行時(shí)變量,如/users/{{id}}

響應(yīng)體結(jié)構(gòu)驗(yàn)證: 支持對(duì)響應(yīng)體的字段類(lèi)型進(jìn)行嚴(yán)格校驗(yàn),多字段、少字段、字段類(lèi)型不符合預(yù)期都會(huì)報(bào)錯(cuò)

非常詳細(xì)的報(bào)錯(cuò)提示: 參見(jiàn)截圖

3. 安裝
yarn add aester
npm i aester -S
4. 使用 4.1. 編寫(xiě)測(cè)試用例
// filename 必須以 test.js結(jié)尾

const Ae = require("aester")
var testData = require("./test-data.js")

// 初始化配置文件
testData = Ae.init(testData)

describe("4XX 5XX error response test", () => {
  test("Get User Info without sessionId", async () => {
    await expect(Ae.send(testData.getOneUser, {id: "1"})).rejects.toHaveProperty("status", 403)
  })

  test("loginByEmail Fail Test", async () => {
    await expect(Ae.send(testData.loginByEmail, {password: "111"})).rejects.toHaveProperty("status", 401)
  })
})

describe("2XX success response test", () => {
  test("loginByEmail Success Test", async () => {
    // 對(duì)于符合預(yù)期的正向測(cè)試,不需要使用expect, 如果響應(yīng)狀態(tài)碼是400以上,或者響應(yīng)體結(jié)構(gòu)不符合預(yù)期,
    // 該測(cè)試用例會(huì)自動(dòng)失敗
    const data = await Ae.send(testData.loginByEmail, {password: "000"})
    Ae.share("sessionId", data.sessionId)
  })

  test("Get User Info", async () => {
    await Ae.send(testData.getOneUser, {id: "1"})
  })
})

describe("2XX success response with error body struct", () => {
  test("StructError test", async () => {
    var data = _.cloneDeep(testData.getOneUser)
    data.resBodyStruct.test = "number" // set a error struct

    await expect(Ae.send(data, {id: "1"})).rejects.toHaveProperty("type", "StructError")
  })
})
4.2. 接口配置文件
// test-data.js
module.exports = {
  $baseUrl: "http://localhost:3000",
  loginByEmail: {
    desc: "login",
    req: {
      method: "post",
      path: "/login",
      headers: { "content-type": "application/x-www-form-urlencoded" },
      data: "[email protected]&password={{password}}",
      params: {
        _test: 1
      }
    },
    resBodyStruct: {
      sessionId: "string"
    }
  },
  getOneUser: {
    desc: "get user info",
    req: {
      path: "/users/{{id}}",
      headers: {
        "sessionId": "{{sessionId}}" // 如果share中有sessionId, 在請(qǐng)求發(fā)送時(shí),會(huì)自動(dòng)將{{sessionId}}替換成真正的值,否則會(huì)被替換成空字符串
      }
    },
    resBodyStruct: {
      id: "string",
      email: "string",
      password: "string",
      userName: "string",
      likes: "array",
      isAdmin: "boolean"
    }
  },
  createOneUser: {
    desc: "create user",
    req: {
      method: "post",
      path: "/users",
      headers: {
        "sessionId": "{{sessionId}}"
      }
    }
  },
  updateOneUser: {
    desc: "update user",
    req: {
      method: "put",
      path: "/users/{{id}}",
      headers: {
        "sessionId": "{{sessionId}}"
      }
    }
  },
  deleteOneUser: {
    desc: "獲取用戶(hù)信息接口",
    req: {
      method: "delete",
      path: "/users/{{id}}",
      headers: {
        "sessionId": "{{sessionId}}"
      }
    }
  }
}
4.3. 運(yùn)行測(cè)試用例

在package.json加入

  "scripts": {
    "test": "jest"
  }

然后運(yùn)行npm test

4.4. 生成html測(cè)試報(bào)告
yarn add jest-html-reporter -D
4.4.1. 方法1

然后在package.json中加入如下字段

"test:report": "jest --reporters="jest-html-reporter""

然后運(yùn)行

npm run test:report
4.4.2. 方法2

創(chuàng)建jest.config.js在項(xiàng)目根目錄

module.exports = {
  verbose: true,
  testEnvironment: "node",
  reporters: [
    "default",
    ["./node_modules/jest-html-reporter", {
      pageTitle: `operation api test ${process.env.testConfigEnv}`,
      includeFailureMsg: true // 詳細(xì)錯(cuò)誤提示
    }]
  ]
}

然后運(yùn)行

npm test
5. 參看測(cè)試結(jié)果 5.1. 正常測(cè)試結(jié)果
 PASS  test/unit.test.js
 PASS  test/index.test.js

Test Suites: 2 passed, 2 total
Tests:       8 passed, 8 total
Snapshots:   0 total
Time:        1.864s
5.2. 接口報(bào)錯(cuò)測(cè)試結(jié)果
          "origin": "null",
          "readyState": 4,
          "requestBuffer": null,
          "requestCache": null,
          "responseBuffer": [Buffer],
          "responseCache": null,
          "responseHeaders": [Object],
          "responseTextCache": "Forbidden",
          "responseURL": "http://localhost:3000/users/1",
          "responseXMLCache": null,
          "send": true,
          "status": 403,
          "statusText": "Forbidden",
          "timeoutFn": null,
          "timeoutId": 0,
          "timeoutStart": 0,
          "totalReceivedChunkSize": 9,
          "uploadComplete": true,
          "uploadListener": false,
        },
      },
      "status": 403,
      "statusText": "Forbidden",
    }

      18 | })
      19 |
    > 20 | test("Get User Info", async () => {
         | ^
      21 |   await Ae.send(testData.getOneUser, {id: "1"})
      22 | })
      23 |

      at Env.it (node_modules/jest-jasmine2/build/jasmine_async.js:102:24)
      at Object. (test/index.test.js:20:1)
5.3. 接口返回響應(yīng)體不符合預(yù)期測(cè)試結(jié)果

例如,resBodyStruct配置sessionId為number格式,但是返回的格式是字符串,將會(huì)如下格式的報(bào)錯(cuò)

    TypeError: Expected a value of type `number` for `sessionId` but received `"123456"`.

      60 |       if (conf.resBodyStruct) {
      61 |         let Scheme = struct(conf.resBodyStruct)
    > 62 |         let result = Scheme.validate(res.data)
         |                             ^
      63 |         if (result.length === 1) {
      64 |           reject(result[0])
      65 |         }

      at Function.Struct.validate.value [as validate] (node_modules/superstruct/src/superstruct.js:78:17)
      at src/index.js:62:29
6. Api 6.1. Aest.init(apiConfs)

初始化配置文件

const Ae = require("aester")

...
var conf = Ae.init(apiConfs)
6.2. Aest.send(apiConf, options)

發(fā)送請(qǐng)求。

options會(huì)與share合并,然后將對(duì)應(yīng)變量渲染到請(qǐng)求模板中。

const Ae = require("aester")

...
Ae.send(testData.getOneUser, {id: "1"}
6.3. Aest.share(key, value)

設(shè)置共享變量

const Ae = require("aester")

...
var conf = Ae.share("token", "123123")
6.4. Aest.getShare()

獲取所有共享變量

const Ae = require("aester")

...
var conf = Ae.getShare() // {token: "123123"}
7. 配置文件說(shuō)明
key 必須? 說(shuō)明
$baseUrl 請(qǐng)求baseUrl

desc | 否 | 接口說(shuō)明
req | 是 | 請(qǐng)求對(duì)象
req.method | 否 | 請(qǐng)求方法,默認(rèn)get
req.path | 是 | 請(qǐng)求路徑
req.headers | 是 | 默認(rèn)為空對(duì)象,默認(rèn)設(shè)置"content-type": "application/json; charset=UTF-8"
resBodyStruct | 否 | 響應(yīng)體格式校驗(yàn)對(duì)象

resBodyStruct字段說(shuō)明

{
  key: keyType
}

字段類(lèi)型支持如下

any: 任意

number: 數(shù)字

array: 數(shù)組

string: 字符串

boolean: 布爾值

null: null

undefined: undefined

object: 對(duì)象類(lèi)型

在字段類(lèi)型后加上?表示字段是否可選

如:

{
  sessionId: "string?" //sessionId是字符串,但是可以沒(méi)有這個(gè)字段
}

更多字段類(lèi)型驗(yàn)證參考:https://github.com/ianstormta...

8. 測(cè)試Aester
npm test

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96817.html

相關(guān)文章

  • jest jenkins搭建自動(dòng)化CI測(cè)試教程

    摘要:想做自動(dòng)化接口測(cè)試時(shí),我也按照打包鏡像的套路走,感覺(jué)走到死胡同。終于自己走通了一遍。點(diǎn)擊進(jìn)去可以發(fā)現(xiàn)測(cè)試報(bào)告。注意測(cè)試報(bào)告并不是生成的。我的項(xiàng)目目錄如下最后如果你也需要自動(dòng)化接口測(cè)試工具可以試試我最近寫(xiě)的一個(gè)工具。 關(guān)于jest和jenkins集成,我走了一些彎路。之前一直用jenkins打包nodejs鏡像。想做nodejs自動(dòng)化接口測(cè)試時(shí),我也按照打包鏡像的套路走,感覺(jué)走到死胡同。...

    ztyzz 評(píng)論0 收藏0
  • 前后端分離模式

    摘要:采用前后端分離模式可以減后臺(tái)負(fù)擔(dān),加快研發(fā)效率,當(dāng)然,前提是前端能做好的話。還是基礎(chǔ)不夠?qū)е碌暮蠖耸欠耧L(fēng)格很多公司采用了前后端分離模式后,后端仍然采用以往的傳統(tǒng)風(fēng)格,這是不合理的,風(fēng)格的應(yīng)該是前后端分離的最佳實(shí)踐。 showImg(https://segmentfault.com/img/bVFC8f?w=690&h=360);早期的web開(kāi)發(fā)是不分前端后端的。互聯(lián)網(wǎng)進(jìn)入Web2.0時(shí)...

    fobnn 評(píng)論0 收藏0
  • 前后端分離模式

    摘要:采用前后端分離模式可以減后臺(tái)負(fù)擔(dān),加快研發(fā)效率,當(dāng)然,前提是前端能做好的話。還是基礎(chǔ)不夠?qū)е碌暮蠖耸欠耧L(fēng)格很多公司采用了前后端分離模式后,后端仍然采用以往的傳統(tǒng)風(fēng)格,這是不合理的,風(fēng)格的應(yīng)該是前后端分離的最佳實(shí)踐。 showImg(https://segmentfault.com/img/bVFC8f?w=690&h=360);早期的web開(kāi)發(fā)是不分前端后端的?;ヂ?lián)網(wǎng)進(jìn)入Web2.0時(shí)...

    DesGemini 評(píng)論0 收藏0
  • 前后端分離模式

    摘要:采用前后端分離模式可以減后臺(tái)負(fù)擔(dān),加快研發(fā)效率,當(dāng)然,前提是前端能做好的話。還是基礎(chǔ)不夠?qū)е碌暮蠖耸欠耧L(fēng)格很多公司采用了前后端分離模式后,后端仍然采用以往的傳統(tǒng)風(fēng)格,這是不合理的,風(fēng)格的應(yīng)該是前后端分離的最佳實(shí)踐。 showImg(https://segmentfault.com/img/bVFC8f?w=690&h=360);早期的web開(kāi)發(fā)是不分前端后端的。互聯(lián)網(wǎng)進(jìn)入Web2.0時(shí)...

    whlong 評(píng)論0 收藏0
  • 4.3 路由設(shè)計(jì)/RESTful API-博客后端Api-NodeJs+Express+Mysql實(shí)

    摘要:路由設(shè)計(jì)路由設(shè)計(jì)以用戶(hù)注冊(cè)為例介紹如何閉環(huán)用戶(hù)注冊(cè)開(kāi)發(fā)注意點(diǎn)使用郵箱注冊(cè)驗(yàn)證郵箱是否注冊(cè)目前真實(shí)開(kāi)發(fā)業(yè)務(wù)大部分都是手機(jī)號(hào)注冊(cè),這塊由于沒(méi)有購(gòu)買(mǎi)短信服務(wù)首先,在文件夾下新建上圖中對(duì)應(yīng)真實(shí)業(yè)務(wù)邏輯現(xiàn)附上業(yè)務(wù)實(shí)現(xiàn)代碼加密?chē)?guó)際化工具類(lèi)用戶(hù)服務(wù) 路由設(shè)計(jì) 路由設(shè)計(jì) 以用戶(hù)注冊(cè)為例介紹如何閉環(huán)用戶(hù)注冊(cè)開(kāi)發(fā)注意點(diǎn):(1)使用郵箱注冊(cè)(2)驗(yàn)證郵箱是否注冊(cè) 【目前真實(shí)開(kāi)發(fā)業(yè)務(wù)大部分都是手機(jī)號(hào)注冊(cè),這塊...

    1fe1se 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<