npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

aester

v0.0.6

Published

![Travis](https://img.shields.io/travis/wangduanduan/Aest.svg)

Readme

1. Aest

Travis

npm Packagist

功能强大的REST接口测试工具, Power By Jest, axios, superstruct, mustache, lodash

2. 特点

  • 非常简单: 大部分工作量在于写配置文件
  • 请求模板: 可以在配置文件中加入运行时变量,如/users/{{id}}
  • 响应体结构验证: 支持对响应体的字段类型进行严格校验,多字段、少字段、字段类型不符合预期都会报错
  • 非常详细的报错提示:

3. 安装

yarn add aester
npm i aester -S

4. 使用

4.1. 编写测试用例

// filename 必须以 test.js结尾

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 () => {
    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, 在请求发送时,会自动将{{sessionId}}替换成真正的值,否则会被替换成空字符串
      }
    },
    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: '获取用户信息接口',
    req: {
      method: 'delete',
      path: '/users/{{id}}',
      headers: {
        'sessionId': '{{sessionId}}'
      }
    }
  }
}

4.3. 运行测试用例

在package.json加入

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

然后运行npm test

4.4. 生成html测试报告

yarn add jest-html-reporter -D

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

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

然后运行

npm run test:report

5. 参看测试结果

5.1. 正常测试结果

 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. 接口报错测试结果

          "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.<anonymous> (test/index.test.js:20:1)

5.3. 接口返回响应体不符合预期测试结果

例如,resBodyStruct配置sessionId为number格式,但是返回的格式是字符串,将会如下格式的报错

    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)

初始化配置文件

const Ae = require('aester')

...
var conf = Ae.init(apiConfs)

6.3. Aest.share(key, value)

设置共享变量

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. 配置文件说明

key | 必须? | 说明 --- | --- | --- $baseUrl | 是 | 请求baseUrl desc | 否 | 接口说明 req | 是 | 请求对象 req.method | 否 | 请求方法,默认get req.path | 是 | 请求路径 req.headers | 是 | 默认为空对象,默认设置'content-type': 'application/json; charset=UTF-8' resBodyStruct | 否 | 响应体格式校验对象

resBodyStruct字段说明

{
  key: keyType
}

字段类型支持如下

  • any: 任意
  • number: 数字
  • array: 数组
  • string: 字符串
  • boolean: 布尔值
  • null: null
  • undefined: undefined
  • object: 对象类型

在字段类型后加上?表示字段是否可选

如:

{
  sessionId: 'string?' //sessionId是字符串,但是可以没有这个字段
}

更多字段类型验证参考:https://github.com/ianstormtaylor/superstruct/blob/master/docs/reference.md

8. 测试Aester

npm test