docs: mock
@ -1,9 +1,16 @@
|
||||
import React, { PureComponent as Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Input, Button, message, Icon, Card, Alert, Modal, Switch, Row, Col } from 'antd';
|
||||
import { Input, Button, message, Icon, Card, Alert, Modal, Switch, Row, Col, Tooltip } from 'antd';
|
||||
import { fetchNewsData } from '../../../reducer/modules/news.js';
|
||||
import { changeGroupMsg, fetchGroupList, setCurrGroup, fetchGroupMsg, updateGroupList, deleteGroup } from '../../../reducer/modules/group.js';
|
||||
import {
|
||||
changeGroupMsg,
|
||||
fetchGroupList,
|
||||
setCurrGroup,
|
||||
fetchGroupMsg,
|
||||
updateGroupList,
|
||||
deleteGroup
|
||||
} from '../../../reducer/modules/group.js';
|
||||
const { TextArea } = Input;
|
||||
import { trim } from '../../../common.js';
|
||||
import _ from 'underscore';
|
||||
@ -16,7 +23,7 @@ const confirm = Modal.confirm;
|
||||
groupList: state.group.groupList,
|
||||
currGroup: state.group.currGroup,
|
||||
curUserRole: state.user.role
|
||||
}
|
||||
};
|
||||
},
|
||||
{
|
||||
changeGroupMsg,
|
||||
@ -38,7 +45,7 @@ class GroupSetting extends Component {
|
||||
custom_field1_name: '',
|
||||
custom_field1_enable: false,
|
||||
custom_field1_rule: false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
@ -52,7 +59,7 @@ class GroupSetting extends Component {
|
||||
updateGroupList: PropTypes.func,
|
||||
deleteGroup: PropTypes.func,
|
||||
groupList: PropTypes.array
|
||||
}
|
||||
};
|
||||
|
||||
initState(props) {
|
||||
this.setState({
|
||||
@ -60,43 +67,41 @@ class GroupSetting extends Component {
|
||||
currGroupDesc: props.currGroup.group_desc,
|
||||
custom_field1_name: props.currGroup.custom_field1.name,
|
||||
custom_field1_enable: props.currGroup.custom_field1.enable
|
||||
})
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// 修改分组名称
|
||||
changeName = (e) => {
|
||||
changeName = e => {
|
||||
this.setState({
|
||||
currGroupName: e.target.value
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
// 修改分组描述
|
||||
changeDesc = (e) => {
|
||||
changeDesc = e => {
|
||||
this.setState({
|
||||
currGroupDesc: e.target.value
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 修改自定义字段名称
|
||||
changeCustomName = (e) => {
|
||||
changeCustomName = e => {
|
||||
let custom_field1_rule = this.state.custom_field1_enable ? !e.target.value : false;
|
||||
this.setState({
|
||||
custom_field1_name: e.target.value,
|
||||
custom_field1_rule
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 修改开启状态
|
||||
changeCustomEnable = (e) => {
|
||||
changeCustomEnable = e => {
|
||||
let custom_field1_rule = e ? !this.state.custom_field1_name : false;
|
||||
this.setState({
|
||||
custom_field1_enable: e,
|
||||
custom_field1_rule
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
|
||||
// console.log('custom_field1',this.props.currGroup.custom_field1)
|
||||
this.initState(this.props);
|
||||
}
|
||||
@ -107,13 +112,13 @@ class GroupSetting extends Component {
|
||||
this.setState({
|
||||
showDangerOptions: !this.state.showDangerOptions
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 编辑分组信息
|
||||
editGroup = async () => {
|
||||
const id = this.props.currGroup._id;
|
||||
if (this.state.custom_field1_rule) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
const res = await this.props.changeGroupMsg({
|
||||
group_name: this.state.currGroupName,
|
||||
@ -128,13 +133,15 @@ class GroupSetting extends Component {
|
||||
if (!res.payload.data.errcode) {
|
||||
message.success('修改成功!');
|
||||
await this.props.fetchGroupList(this.props.groupList);
|
||||
this.props.updateGroupList(this.props.groupList)
|
||||
const currGroup = _.find(this.props.groupList, (group) => { return + group._id === + id });
|
||||
this.props.updateGroupList(this.props.groupList);
|
||||
const currGroup = _.find(this.props.groupList, group => {
|
||||
return +group._id === +id;
|
||||
});
|
||||
this.props.setCurrGroup(currGroup);
|
||||
this.props.fetchGroupMsg(this.props.currGroup._id);
|
||||
this.props.fetchNewsData(this.props.currGroup._id, "group", 1, 10)
|
||||
this.props.fetchNewsData(this.props.currGroup._id, 'group', 1, 10);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 删除分组
|
||||
|
||||
@ -143,51 +150,56 @@ class GroupSetting extends Component {
|
||||
const { currGroup } = that.props;
|
||||
const res = await this.props.deleteGroup({ id: currGroup._id });
|
||||
if (!res.payload.data.errcode) {
|
||||
message.success('删除成功')
|
||||
message.success('删除成功');
|
||||
await that.props.fetchGroupList();
|
||||
const currGroup = that.props.groupList[0] || { group_name: '', group_desc: '' };
|
||||
that.setState({ groupList: that.props.groupList });
|
||||
that.props.setCurrGroup(currGroup)
|
||||
that.props.setCurrGroup(currGroup);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 删除分组的二次确认
|
||||
showConfirm = () => {
|
||||
const that = this;
|
||||
confirm({
|
||||
title: "确认删除 " + that.props.currGroup.group_name + " 分组吗?",
|
||||
content: <div style={{ marginTop: '10px', fontSize: '13px', lineHeight: '25px' }}>
|
||||
<Alert message="警告:此操作非常危险,会删除该分组下面所有项目和接口,并且无法恢复!" type="warning" />
|
||||
<div style={{ marginTop: '16px' }}>
|
||||
<p><b>请输入分组名称确认此操作:</b></p>
|
||||
<Input id="group_name" />
|
||||
title: '确认删除 ' + that.props.currGroup.group_name + ' 分组吗?',
|
||||
content: (
|
||||
<div style={{ marginTop: '10px', fontSize: '13px', lineHeight: '25px' }}>
|
||||
<Alert
|
||||
message="警告:此操作非常危险,会删除该分组下面所有项目和接口,并且无法恢复!"
|
||||
type="warning"
|
||||
/>
|
||||
<div style={{ marginTop: '16px' }}>
|
||||
<p>
|
||||
<b>请输入分组名称确认此操作:</b>
|
||||
</p>
|
||||
<Input id="group_name" />
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
),
|
||||
onOk() {
|
||||
const groupName = trim(document.getElementById('group_name').value);
|
||||
if (that.props.currGroup.group_name !== groupName) {
|
||||
message.error('分组名称有误')
|
||||
message.error('分组名称有误');
|
||||
return new Promise((resolve, reject) => {
|
||||
reject('error')
|
||||
})
|
||||
reject('error');
|
||||
});
|
||||
} else {
|
||||
that.deleteGroup()
|
||||
that.deleteGroup();
|
||||
}
|
||||
|
||||
},
|
||||
iconType: 'delete',
|
||||
onCancel() { }
|
||||
onCancel() {}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
|
||||
// 切换分组时,更新分组信息并关闭删除分组操作
|
||||
if (this.props.currGroup._id !== nextProps.currGroup._id) {
|
||||
this.initState(nextProps);
|
||||
this.setState({
|
||||
showDangerOptions: false
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,53 +207,99 @@ class GroupSetting extends Component {
|
||||
return (
|
||||
<div className="m-panel card-panel card-panel-s panel-group">
|
||||
<Row type="flex" justify="space-around" className="row" align="middle">
|
||||
<Col span={4} className="label">分组名:</Col>
|
||||
<Col span={4} className="label">
|
||||
分组名:
|
||||
</Col>
|
||||
<Col span={20}>
|
||||
<Input size="large" placeholder="请输入分组名称" value={this.state.currGroupName} onChange={this.changeName}></Input>
|
||||
<Input
|
||||
size="large"
|
||||
placeholder="请输入分组名称"
|
||||
value={this.state.currGroupName}
|
||||
onChange={this.changeName}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row type="flex" justify="space-around" className="row" align="middle">
|
||||
<Col span={4} className="label">简介:</Col>
|
||||
<Col span={4} className="label">
|
||||
简介:
|
||||
</Col>
|
||||
<Col span={20}>
|
||||
<TextArea size="large" rows={3} placeholder="请输入分组描述" value={this.state.currGroupDesc} onChange={this.changeDesc}></TextArea>
|
||||
<TextArea
|
||||
size="large"
|
||||
rows={3}
|
||||
placeholder="请输入分组描述"
|
||||
value={this.state.currGroupDesc}
|
||||
onChange={this.changeDesc}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row type="flex" justify="space-around" className="row" align="middle">
|
||||
<Col span={4} className="label">接口自定义字段:</Col>
|
||||
<Col span={4} className="label">
|
||||
接口自定义字段
|
||||
<Tooltip title={'可以在接口中添加 额外字段 数据'}>
|
||||
<Icon type="question-circle-o" style={{ width: '10px' }} />
|
||||
</Tooltip> :
|
||||
</Col>
|
||||
<Col span={12} style={{ position: 'relative' }}>
|
||||
<Input placeholder="请输入自定义字段名称" style={{ borderColor: this.state.custom_field1_rule ? '#f5222d' : '' }} value={this.state.custom_field1_name} onChange={this.changeCustomName} />
|
||||
<div className="custom-field-rule" style={{ display: this.state.custom_field1_rule ? 'block' : 'none' }}>自定义字段名称不能为空</div>
|
||||
<Input
|
||||
placeholder="请输入自定义字段名称"
|
||||
style={{ borderColor: this.state.custom_field1_rule ? '#f5222d' : '' }}
|
||||
value={this.state.custom_field1_name}
|
||||
onChange={this.changeCustomName}
|
||||
/>
|
||||
<div
|
||||
className="custom-field-rule"
|
||||
style={{ display: this.state.custom_field1_rule ? 'block' : 'none' }}
|
||||
>
|
||||
自定义字段名称不能为空
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={2} className="label">
|
||||
开启:
|
||||
</Col>
|
||||
<Col span={2} className="label">开启:</Col>
|
||||
<Col span={6}>
|
||||
<Switch checked={this.state.custom_field1_enable} checkedChildren="开" unCheckedChildren="关" onChange={this.changeCustomEnable} />
|
||||
<Switch
|
||||
checked={this.state.custom_field1_enable}
|
||||
checkedChildren="开"
|
||||
unCheckedChildren="关"
|
||||
onChange={this.changeCustomEnable}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
<Row type="flex" justify="center" className="row save">
|
||||
<Col span={4} className="save-button">
|
||||
<Button className="m-btn btn-save" icon="save" type="primary" onClick={this.editGroup} >保 存</Button>
|
||||
<Button className="m-btn btn-save" icon="save" type="primary" onClick={this.editGroup}>
|
||||
保 存
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
{/* 只有超级管理员能删除分组 */}
|
||||
{this.props.curUserRole === "admin" ?
|
||||
{this.props.curUserRole === 'admin' ? (
|
||||
<Row type="flex" justify="center" className="danger-container">
|
||||
<Col span={24} className="title">
|
||||
<h2 className="content"><Icon type="exclamation-circle-o" /> 危险操作</h2>
|
||||
<Button onClick={this.toggleDangerOptions}>查 看<Icon type={this.state.showDangerOptions ? 'up' : 'down'} /></Button>
|
||||
<h2 className="content">
|
||||
<Icon type="exclamation-circle-o" /> 危险操作
|
||||
</h2>
|
||||
<Button onClick={this.toggleDangerOptions}>
|
||||
查 看<Icon type={this.state.showDangerOptions ? 'up' : 'down'} />
|
||||
</Button>
|
||||
</Col>
|
||||
{this.state.showDangerOptions ?
|
||||
{this.state.showDangerOptions ? (
|
||||
<Card noHovering={true} className="card-danger" style={{ width: '100%' }}>
|
||||
<div className="card-danger-content">
|
||||
<h3>删除分组</h3>
|
||||
<p>分组一旦删除,将无法恢复数据,请慎重操作!</p>
|
||||
<p>只有超级管理员有权限删除分组。</p>
|
||||
</div>
|
||||
<Button type="danger" ghost className="card-danger-btn" onClick={this.showConfirm}>删除</Button>
|
||||
</Card> : null}
|
||||
</Row> : null}
|
||||
<Button type="danger" ghost className="card-danger-btn" onClick={this.showConfirm}>
|
||||
删除
|
||||
</Button>
|
||||
</Card>
|
||||
) : null}
|
||||
</Row>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,6 @@ const mapping = function(data, index) {
|
||||
case 'integer':
|
||||
return SchemaInt(data)
|
||||
default:
|
||||
console.log(data);
|
||||
return SchemaOther(data)
|
||||
}
|
||||
|
||||
|
BIN
doc/images/autoTest.png
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
doc/images/autoTestResult.png
Normal file
After Width: | Height: | Size: 132 KiB |
BIN
doc/images/jsonSchema.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
doc/images/usage/json-schema-demo.jpg
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
doc/images/usage/json-schema-mock.jpg
Normal file
After Width: | Height: | Size: 148 KiB |
@ -1,5 +1,7 @@
|
||||
## 后端 hookList
|
||||
目前 hooksList 只有下面列出的部分,如果您有其他的需求,可提建议到 github 或者 qq群
|
||||
|
||||
目前 hooksList 只有下面列出的部分,如果您有其他的需求,可提建议到 github 或者 qq 群
|
||||
|
||||
```
|
||||
/**
|
||||
* 钩子配置
|
||||
@ -7,7 +9,7 @@
|
||||
var hooks = {
|
||||
/**
|
||||
* 第三方sso登录钩子,暂只支持设置一个
|
||||
* @param ctx
|
||||
* @param ctx
|
||||
* @return 必需返回一个 promise 对象,resolve({username: '', email: ''})
|
||||
*/
|
||||
'third_login': {
|
||||
@ -77,9 +79,9 @@ var hooks = {
|
||||
* projectData: project,
|
||||
interfaceData: interfaceData,
|
||||
ctx: ctx,
|
||||
mockJson: res
|
||||
mockJson: res
|
||||
* }
|
||||
*
|
||||
*
|
||||
*/
|
||||
mock_after: {
|
||||
type: 'multi',
|
||||
@ -88,7 +90,7 @@ var hooks = {
|
||||
/**
|
||||
* 增加路由的钩子
|
||||
* type Sync
|
||||
* @param addPluginRouter Function
|
||||
* @param addPluginRouter Function
|
||||
* addPLuginPLugin(config)
|
||||
* config = {
|
||||
* path, // String
|
||||
@ -105,12 +107,13 @@ var hooks = {
|
||||
```
|
||||
|
||||
## 前端 hookList
|
||||
|
||||
```
|
||||
/**
|
||||
* type component 组件
|
||||
* listener 监听函数
|
||||
* mulit 是否绑定多个监听函数
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
hooks = {
|
||||
@ -127,7 +130,7 @@ hooks = {
|
||||
* @param Object exportDataModule
|
||||
* @param projectId
|
||||
* @info
|
||||
* exportDataModule = {};
|
||||
* exportDataModule = {};
|
||||
* exportDataModule.pdf = {
|
||||
* name: 'Pdf',
|
||||
* route: '/api/plugin/export/pdf',
|
||||
@ -142,11 +145,11 @@ hooks = {
|
||||
/**
|
||||
* 导入数据
|
||||
* @param importDataModule
|
||||
*
|
||||
*
|
||||
* @info
|
||||
* 可参考 vendors/exts/yapi-plugin-import-swagger插件
|
||||
* importDataModule = {};
|
||||
*
|
||||
* importDataModule = {};
|
||||
*
|
||||
*/
|
||||
import_data: {
|
||||
type: 'listener',
|
||||
@ -156,7 +159,7 @@ hooks = {
|
||||
/**
|
||||
* 接口页面 tab 钩子
|
||||
* @param InterfaceTabs
|
||||
*
|
||||
*
|
||||
* @info
|
||||
* 可参考 vendors/exts/yapi-plugin-advanced-mock
|
||||
* let InterfaceTabs = {
|
||||
@ -180,4 +183,4 @@ hooks = {
|
||||
listener: []
|
||||
}
|
||||
};
|
||||
```
|
||||
```
|
||||
|
@ -28,6 +28,10 @@
|
||||
### 返回数据设置
|
||||
|
||||
- 返回数据分为 `json` & `raw` 两种形式。基于 mockjs (具体使用方法详见<a href="./mock.html">Mock 介绍</a>)和 json5,使用注释方式写参数说明。 为了方便数据编写可以按F9来使用全局编辑
|
||||
- 选择json-schema 则进入了 json 结构可视化编辑器形式, 数据以 json schema 格式解析 <a target="_blank" href="https://www.jianshu.com/p/8278eb2458c4?winzoom=1">快速入门 Json Schema </a>。
|
||||
|
||||
<img src="./images/jsonSchema.png" />
|
||||
|
||||
|
||||
|
||||
### 备注 & 其他
|
||||
|
@ -1,4 +1,5 @@
|
||||
## 介绍
|
||||
|
||||
<p style='text-indent:2em;line-height:1.8em'>Web 应用通常是前后端分离开发的,后端提供调用的接口,前端使用接口返回 json 数据渲染到 UI,接口测试就是保证后端接口的数据正确性。
|
||||
|
||||
对于很多团队,接口测试就是手动运行接口,肉眼比对接口返回的数据,这样的操作流程效率低下,容易出错。使用 YApi 只需要在可视化 GUI 下,配置下每个接口的入参和对 RESPONSE 断言,即可实现对接口的自动化测试,大大提升了接口测试的效率。<a target="_blank" href="https://blog.ymfe.org/api-autotest/#more">自动化测试实践</a></p>
|
||||
@ -15,18 +16,20 @@
|
||||
|
||||
## 编辑测试用例
|
||||
|
||||
### Mock参数
|
||||
### Mock 参数
|
||||
|
||||
Mock 参数每次请求都会生成随机字符串
|
||||
|
||||
<img class="doc-img" style="width:100%" src="./images/usage/case-edit.jpg" />
|
||||
|
||||
#### 变量参数
|
||||
|
||||
YApi 提供了强大的变量参数功能,你可以在测试的时候使用前面接口的 `参数` 或 `返回值` 作为 `后面接口的参数`,即使接口之间存在依赖,也可以轻松 **一键测试~**
|
||||
YApi 提供了强大的变量参数功能,你可以在测试的时候使用前面接口的 `参数` 或 `返回值` 作为 `后面接口的参数`,即使接口之间存在依赖,也可以轻松 **一键测试~**
|
||||
|
||||
> Tips: 参数只能是测试过程中排在前面的接口中的变量参数
|
||||
|
||||
格式:
|
||||
|
||||
```
|
||||
$.{key}.{params|body}.{path}
|
||||
```
|
||||
@ -37,6 +40,7 @@ $.{key}.{params|body}.{path}
|
||||
文章列表接口需要传参数: `当前标题(id)`,而这个 id 需要通过 `导航标题` 的返回值获取,这时应在 `文章列表` 的参数输入框中根据前者的 key 找到对应 id。
|
||||
|
||||
`导航标题` 的参数和返回值有如下结构:
|
||||
|
||||
<div style="margin: 16px 0;">
|
||||
<span style="display: inline-block; width: 60px;vertical-align: top;">参数:</span>
|
||||
<img style="width: 165px;" src="./images/usage/case_key_res_query.png" />
|
||||
@ -51,14 +55,12 @@ $.{key}.{params|body}.{path}
|
||||
|
||||
其中 **$.** 是使用 **动态变量** 的标志,$.269.**params** 即表示 key 值为 269 用例的请求参数,$.269.**body** 即表示 key 值为 269 用例的返回值。
|
||||
|
||||
如果requestBody是json格式也可以在json中写变量参数,如下图:
|
||||
如果 requestBody 是 json 格式也可以在 json 中写变量参数,如下图:
|
||||
<img class="doc-img" style="width: 624px;" src="./images/usage/case_key_body_json.png" />
|
||||
|
||||
|
||||
> Tips: 上下拖动测试集合的列表项可以调整测试的顺序。
|
||||
|
||||
目前yapi中的`query`,`body`,`header`和`pathParam`的输入参数已经支持点击选择功能。无需自己填写表达式,只需在弹窗中选择需要展示的表达式即可。 输入选项包括`常量`,`mock数据`,在测试集合中也支持`变量`选择。
|
||||
具体用法:单击编辑按钮打开表达式生成器,点击需要的数据创建表达式,这里也可以实时查看表达式结果。
|
||||
目前 yapi 中的`query`,`body`,`header`和`pathParam`的输入参数已经支持点击选择功能。无需自己填写表达式,只需在弹窗中选择需要展示的表达式即可。 输入选项包括`常量`,`mock数据`,在测试集合中也支持`变量`选择。具体用法:单击编辑按钮打开表达式生成器,点击需要的数据创建表达式,这里也可以实时查看表达式结果。
|
||||
|
||||
<img class="doc-img" style="width: 800px;" src="./images/usage/modal-postman.gif" />
|
||||
|
||||
@ -67,6 +69,14 @@ $.{key}.{params|body}.{path}
|
||||
<img class="doc-img" style="width: 800px;" src="./images/usage/modal-postman-tips.png" />
|
||||
|
||||
## 自动化测试
|
||||
|
||||
点击自动化测试,出现如下弹窗,用户访问该 url 就可以获取当前测试用例的所有测试结果
|
||||
|
||||
<img src="./images/autoTest.png" />
|
||||
<img src="./images/autoTestResult.png" />
|
||||
|
||||
## 断言
|
||||
|
||||
可通过 js 脚本写断言,实现精准测试,在接口用例页面点击 Test 编辑。
|
||||
|
||||
<!-- <video style="width:800px" controls="controls" autoplay="autoplay">
|
||||
@ -75,20 +85,22 @@ Your browser does not support the video tag.
|
||||
</video> -->
|
||||
|
||||
### 公共变量
|
||||
#### 1.assert
|
||||
|
||||
#### 1.assert
|
||||
|
||||
断言函数,详细 api 可查看 <a target="_blank" href="https://nodejs.org/dist/latest-v8.x/docs/api/assert.html">document</a>
|
||||
|
||||
##### 常用 api:
|
||||
* assert(value)
|
||||
|
||||
判断 value 是否为 truth, 例如 assert(1) 通过, assert(0) 不通过,只要 value 不是 null, 0, false等值验证通过
|
||||
* assert(value)
|
||||
|
||||
* assert.equal(actual, expected)
|
||||
判断 value 是否为 truth, 例如 assert(1) 通过, assert(0) 不通过,只要 value 不是 null, 0, false 等值验证通过
|
||||
|
||||
* assert.equal(actual, expected)
|
||||
|
||||
判断 actual 是否等于 expected,例如 assert(1, 1)通过
|
||||
|
||||
* assert.notEqual(actual, expected)
|
||||
* assert.notEqual(actual, expected)
|
||||
|
||||
判断 actual 是否不等于 expected
|
||||
|
||||
@ -102,32 +114,32 @@ Your browser does not support the video tag.
|
||||
|
||||
#### 2.status
|
||||
|
||||
http 状态码
|
||||
http 状态码
|
||||
|
||||
#### 3.params
|
||||
|
||||
http request params, 合并了 query 和 body
|
||||
http request params, 合并了 query 和 body
|
||||
|
||||
#### 4.body
|
||||
#### 4.body
|
||||
|
||||
返回 response body
|
||||
返回 response body
|
||||
|
||||
#### 5.header
|
||||
#### 5.header
|
||||
|
||||
返回 response header
|
||||
返回 response header
|
||||
|
||||
#### 6.records
|
||||
#### 6.records
|
||||
|
||||
记录的 http 请求信息,假设需要获取 key 为 555 的接口参数或者响应数据,可通过 records[555].params 或 records[555].body 获取
|
||||
记录的 http 请求信息,假设需要获取 key 为 555 的接口参数或者响应数据,可通过 records[555].params 或 records[555].body 获取
|
||||
|
||||
#### 7.log
|
||||
#### 7.log
|
||||
|
||||
log(message) 函数,调试时使用,log 信息仅仅在断言失败后打印
|
||||
|
||||
log(message) 函数,调试时使用,log 信息仅仅在断言失败后打印
|
||||
|
||||
### 示例
|
||||
|
||||
```
|
||||
assert.equal(body.errcode, 0)
|
||||
assert.equal(body.data.group_name, 'testGroup')
|
||||
assert.equal(status, 200)
|
||||
```
|
||||
|
||||
|
@ -14,11 +14,27 @@
|
||||
|
||||
项目 -> 接口编辑 -> 返回数据设置
|
||||
|
||||
返回数据设置有两种方式,最新版本默认是基于 `json-schema` 定义数据结构,另外一种是基于 `json+注释` 的方式,请根据实际情况灵活选择使用。
|
||||
|
||||
|
||||
## 方式1. json-schema
|
||||
<img src="./images/usage/json-schema-demo.jpg" />
|
||||
|
||||
开启 json-schema 功能后,将不再使用 mockjs 解析定义的返回数据,而是根据 json-schema 定义的数据结构,生成随机数据。
|
||||
|
||||
### 如何生成随机的邮箱或 ip?
|
||||
|
||||
<img src="./images/usage/json-schema-mock.jpg" />
|
||||
|
||||
点击高级设置,选择 `format` 选项,比如选择 `email` 则该字段生成随机邮箱字符串。
|
||||
|
||||
## 方式2. json5+注释
|
||||
|
||||
<img src="./images/usage/mock-demo.jpg" />
|
||||
|
||||
> 注:开启 json-schema 功能后,将不再使用 mockjs 解析定义的返回数据,而是根据 json-schema 定义的数据结构,生成随机数据。
|
||||
|
||||
## 原理
|
||||
|
||||
### 原理
|
||||
YApi Mock 功能基于 node 和 [mockjs](http://mockjs.com),跟 Mockjs 区别是 yapi 基于 json 定义 mock ,无法使用 mockjs 原有的函数功能,正则表达式需要基于 rule 书写,示例如下:
|
||||
|
||||
```
|
||||
@ -41,9 +57,9 @@ YApi Mock 功能基于 node 和 [mockjs](http://mockjs.com),跟 Mockjs 区别
|
||||
|
||||
其他基本用法请查看:<a href="http://mockjs.com/examples.html">Mockjs 官网</a>
|
||||
|
||||
## 如何使用 Mock
|
||||
### 如何使用 Mock
|
||||
|
||||
### 1 在 js 代码直接请求yapi提供的 mock 地址(不用担心跨域问题)
|
||||
#### 1 在 js 代码直接请求yapi提供的 mock 地址(不用担心跨域问题)
|
||||
|
||||
在代码直接请求 yapi 提供的 mock 地址,以 jQuery 为例:
|
||||
|
||||
@ -54,11 +70,11 @@ $.post(prefix+'/baseapi/path', {username: 'xxx'}, function(res){
|
||||
})
|
||||
````
|
||||
|
||||
### 2 基于本地服务器反向代理
|
||||
#### 2 基于本地服务器反向代理
|
||||
|
||||
优点:不用修改项目代码
|
||||
|
||||
#### 2.1 基于 nginx 反向代理
|
||||
##### 2.1 基于 nginx 反向代理
|
||||
|
||||
```` nginx
|
||||
location /baseapi
|
||||
@ -67,7 +83,7 @@ proxy_pass http://yapi.xxx.com/mock/2817/baseapi; #baseapi后面没有"/"
|
||||
}
|
||||
````
|
||||
|
||||
#### 2.2 基于 ykit mock功能
|
||||
##### 2.2 基于 ykit mock功能
|
||||
|
||||
```javascript
|
||||
{
|
||||
@ -82,7 +98,7 @@ proxy_pass http://yapi.xxx.com/mock/2817/baseapi; #baseapi后面没有"/"
|
||||
|
||||
|
||||
|
||||
#### 2.3 基于 ykit Jerry 代理
|
||||
##### 2.3 基于 ykit Jerry 代理
|
||||
|
||||
假设您本地服务器访问地址是: http://xxx.com
|
||||
|
||||
@ -90,13 +106,13 @@ proxy_pass http://yapi.xxx.com/mock/2817/baseapi; #baseapi后面没有"/"
|
||||
|
||||
<span id="mock"></span>
|
||||
|
||||
#### 2.4 基于 Charles 代理
|
||||
##### 2.4 基于 Charles 代理
|
||||
|
||||
点击 Charles 工具栏下的 tools >> Rewrite Settings 填写如下信息:
|
||||
|
||||
<img src="./images/charles.png" width="60%" />
|
||||
|
||||
## Mock 语法规范
|
||||
### Mock 语法规范
|
||||
>了解更多Mock详情:[Mock.js 官方文档](http://mockjs.com/examples.html)
|
||||
|
||||
Mock.js 的语法规范包括两部分:
|
||||
@ -130,7 +146,7 @@ Mock.js 的语法规范包括两部分:
|
||||
|
||||
下面提供了6种生成规则以及示例包括 String、Number、Boolean、Object、Array:
|
||||
|
||||
### 1. 属性值是字符串 String
|
||||
#### 1. 属性值是字符串 String
|
||||
|
||||
```
|
||||
1. 'name|min-max': string
|
||||
@ -141,7 +157,7 @@ Mock.js 的语法规范包括两部分:
|
||||
|
||||
通过重复 string 生成一个字符串,重复次数等于 count。
|
||||
```
|
||||
### 2. 属性值是数字 Number
|
||||
#### 2. 属性值是数字 Number
|
||||
```
|
||||
1. 'name|+1': number
|
||||
|
||||
@ -171,7 +187,7 @@ Mock.mock({
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 属性值是布尔型 Boolean
|
||||
#### 3. 属性值是布尔型 Boolean
|
||||
```
|
||||
1. 'name|1': boolean
|
||||
|
||||
@ -181,7 +197,7 @@ Mock.mock({
|
||||
|
||||
随机生成一个布尔值,值为 value 的概率是 min / (min + max),值为 !value 的概率是 max / (min + max)。
|
||||
```
|
||||
### 4. 属性值是对象 Object
|
||||
#### 4. 属性值是对象 Object
|
||||
```
|
||||
1. 'name|count': object
|
||||
|
||||
@ -191,7 +207,7 @@ Mock.mock({
|
||||
|
||||
从属性值 object 中随机选取 min 到 max 个属性。
|
||||
```
|
||||
### 5. 属性值是数组 Array
|
||||
#### 5. 属性值是数组 Array
|
||||
```
|
||||
1. 'name|1': array
|
||||
|
||||
@ -211,7 +227,7 @@ Mock.mock({
|
||||
```
|
||||
|
||||
<span id = "DPD"></span>
|
||||
### 数据占位符定义规范(Data Placeholder Definition,DPD)
|
||||
#### 数据占位符定义规范(Data Placeholder Definition,DPD)
|
||||
```
|
||||
占位符 只是在属性值字符串中占个位置,并不出现在最终的属性值中。
|
||||
|
||||
|
@ -128,4 +128,8 @@ context.utils = {
|
||||
sha512 //转换字符串为 sha512 编码
|
||||
unbase64 //转换 base64 编码为字符串
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
## token配置
|
||||
|
||||
每个项目都有唯一的标识token,用户可以使用这个token值来请求项目的所有资源数据。目前用到的地方是接口的<a href="./case.html">自动化测试</a>,用户不需要登录就可以访问接口测试结果信息。
|
@ -35,6 +35,7 @@ function postman(importDataModule){
|
||||
name: query[item].key,
|
||||
desc: query[item].description,
|
||||
example: query[item].value,
|
||||
value: query[item].value,
|
||||
required: query[item].enabled ? '1' : '0'
|
||||
});
|
||||
}
|
||||
@ -63,6 +64,7 @@ function postman(importDataModule){
|
||||
res.push({
|
||||
name: body_form[item].key,
|
||||
example: body_form[item].value,
|
||||
value: body_form[item].value,
|
||||
type: body_form[item].type,
|
||||
required: body_form[item].enabled ? '1': '0',
|
||||
desc: body_form[item].description
|
||||
|
@ -57,8 +57,10 @@ class interfaceModel extends baseModel {
|
||||
},
|
||||
req_body_is_json_schema: { type: Boolean, default: false },
|
||||
req_body_form: [{
|
||||
name: String, type: { type: String, enum: ['text', 'file'] },
|
||||
name: String,
|
||||
type: { type: String, enum: ['text', 'file'] },
|
||||
example: String,
|
||||
value: String,
|
||||
desc: String,
|
||||
required: {
|
||||
type: String,
|
||||
|
@ -167,6 +167,10 @@
|
||||
<li >
|
||||
<a href="#自动化测试">自动化测试</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="#断言">断言</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -190,9 +194,9 @@
|
||||
<p>在测试列表可以看到每个测试用例的 key,还有 开始测试、报告等功能</p>
|
||||
<p>点击开始测试会按照 case 定义的参数从上往下一个一个进行测试,如果顺序有问题,可以拖动调整</p>
|
||||
<p>测试完成之后,点击报告查看该次请求的结果</p>
|
||||
<h2 class="subject" id="编辑测试用例">编辑测试用例 <a class="hashlink" href="#编辑测试用例">#</a></h2><h3 class="subject" id="Mock参数">Mock参数 <a class="hashlink" href="#Mock参数">#</a></h3><p>Mock 参数每次请求都会生成随机字符串</p>
|
||||
<h2 class="subject" id="编辑测试用例">编辑测试用例 <a class="hashlink" href="#编辑测试用例">#</a></h2><h3 class="subject" id="Mock_参数">Mock 参数 <a class="hashlink" href="#Mock_参数">#</a></h3><p>Mock 参数每次请求都会生成随机字符串</p>
|
||||
<p><img class="doc-img" style="width:100%" src="./images/usage/case-edit.jpg" /></p>
|
||||
<h4 class="subject" id="变量参数">变量参数 <a class="hashlink" href="#变量参数">#</a></h4><p>YApi 提供了强大的变量参数功能,你可以在测试的时候使用前面接口的 <code>参数</code> 或 <code>返回值</code> 作为 <code>后面接口的参数</code>,即使接口之间存在依赖,也可以轻松 <strong>一键测试~</strong> </p>
|
||||
<h4 class="subject" id="变量参数">变量参数 <a class="hashlink" href="#变量参数">#</a></h4><p>YApi 提供了强大的变量参数功能,你可以在测试的时候使用前面接口的 <code>参数</code> 或 <code>返回值</code> 作为 <code>后面接口的参数</code>,即使接口之间存在依赖,也可以轻松 <strong>一键测试~</strong></p>
|
||||
<blockquote>
|
||||
<p>Tips: 参数只能是测试过程中排在前面的接口中的变量参数</p>
|
||||
</blockquote>
|
||||
@ -214,42 +218,44 @@
|
||||
<p>则 <code>文章列表</code> 的参数可以如下配置:
|
||||
<img class="doc-img" style="width: 624px;" src="./images/usage/case_key_query.png" /></p>
|
||||
<p>其中 <strong>$.</strong> 是使用 <strong>动态变量</strong> 的标志,$.269.<strong>params</strong> 即表示 key 值为 269 用例的请求参数,$.269.<strong>body</strong> 即表示 key 值为 269 用例的返回值。</p>
|
||||
<p>如果requestBody是json格式也可以在json中写变量参数,如下图:
|
||||
<p>如果 requestBody 是 json 格式也可以在 json 中写变量参数,如下图:
|
||||
<img class="doc-img" style="width: 624px;" src="./images/usage/case_key_body_json.png" /></p>
|
||||
<blockquote>
|
||||
<p>Tips: 上下拖动测试集合的列表项可以调整测试的顺序。</p>
|
||||
</blockquote>
|
||||
<p>目前yapi中的<code>query</code>,<code>body</code>,<code>header</code>和<code>pathParam</code>的输入参数已经支持点击选择功能。无需自己填写表达式,只需在弹窗中选择需要展示的表达式即可。 输入选项包括<code>常量</code>,<code>mock数据</code>,在测试集合中也支持<code>变量</code>选择。
|
||||
具体用法:单击编辑按钮打开表达式生成器,点击需要的数据创建表达式,这里也可以实时查看表达式结果。</p>
|
||||
<p>目前 yapi 中的<code>query</code>,<code>body</code>,<code>header</code>和<code>pathParam</code>的输入参数已经支持点击选择功能。无需自己填写表达式,只需在弹窗中选择需要展示的表达式即可。 输入选项包括<code>常量</code>,<code>mock数据</code>,在测试集合中也支持<code>变量</code>选择。具体用法:单击编辑按钮打开表达式生成器,点击需要的数据创建表达式,这里也可以实时查看表达式结果。</p>
|
||||
<p><img class="doc-img" style="width: 800px;" src="./images/usage/modal-postman.gif" /></p>
|
||||
<blockquote>
|
||||
<p>Tips: 在测试集合中插入变量参数可以会出现下图的提示信息,这是正常现象。因为该参数只能在各个接口顺序执行的时候才能拉到变量参数中的值</p>
|
||||
</blockquote>
|
||||
<p><img class="doc-img" style="width: 800px;" src="./images/usage/modal-postman-tips.png" /></p>
|
||||
<h2 class="subject" id="自动化测试">自动化测试 <a class="hashlink" href="#自动化测试">#</a></h2><p>可通过 js 脚本写断言,实现精准测试,在接口用例页面点击 Test 编辑。</p>
|
||||
<h2 class="subject" id="自动化测试">自动化测试 <a class="hashlink" href="#自动化测试">#</a></h2><p>点击自动化测试,出现如下弹窗,用户访问该 url 就可以获取当前测试用例的所有测试结果</p>
|
||||
<p><img src="./images/autoTest.png" />
|
||||
<img src="./images/autoTestResult.png" /></p>
|
||||
<h2 class="subject" id="断言">断言 <a class="hashlink" href="#断言">#</a></h2><p>可通过 js 脚本写断言,实现精准测试,在接口用例页面点击 Test 编辑。</p>
|
||||
<!-- <video style="width:800px" controls="controls" autoplay="autoplay">
|
||||
<source src="http://yapi.demo.qunar.com/publicapi/auto-test.mp4" type="video/mp4" />
|
||||
Your browser does not support the video tag.
|
||||
</video> -->
|
||||
<h3 class="subject" id="公共变量">公共变量 <a class="hashlink" href="#公共变量">#</a></h3><h4 class="subject" id="1.assert">1.assert <a class="hashlink" href="#1.assert">#</a></h4><p>断言函数,详细 api 可查看 <a target="_blank" href="https://nodejs.org/dist/latest-v8.x/docs/api/assert.html">document</a></p>
|
||||
<h5 class="subject" id="常用_api_">常用 api: <a class="hashlink" href="#常用_api_">#</a></h5><ul>
|
||||
<li><p>assert(value) </p>
|
||||
<p>判断 value 是否为 truth, 例如 assert(1) 通过, assert(0) 不通过,只要 value 不是 null, 0, false等值验证通过</p>
|
||||
</li><li><p>assert.equal(actual, expected) </p>
|
||||
<li><p>assert(value)</p>
|
||||
<p>判断 value 是否为 truth, 例如 assert(1) 通过, assert(0) 不通过,只要 value 不是 null, 0, false 等值验证通过</p>
|
||||
</li><li><p>assert.equal(actual, expected)</p>
|
||||
<p>判断 actual 是否等于 expected,例如 assert(1, 1)通过</p>
|
||||
</li><li><p>assert.notEqual(actual, expected) </p>
|
||||
</li><li><p>assert.notEqual(actual, expected)</p>
|
||||
<p>判断 actual 是否不等于 expected</p>
|
||||
</li><li><p>assert.deepEqual(actual, expected)</p>
|
||||
<p>假设: actual = {a:1} 是一个对象,即便 expected = {a:1},如果使用 assert.equal 可能也是不相等的,因为在 js 引用的只是对象的一个指针,需要使用 assert.deepEqual 比较两个对象是否相等</p>
|
||||
</li><li><p>assert.notDeepEaual(actual, expected)</p>
|
||||
<p>深度比较两个对象是否不相等</p>
|
||||
</li></ul>
|
||||
<h4 class="subject" id="2.status">2.status <a class="hashlink" href="#2.status">#</a></h4><p> http 状态码</p>
|
||||
<h4 class="subject" id="3.params">3.params <a class="hashlink" href="#3.params">#</a></h4><p> http request params, 合并了 query 和 body</p>
|
||||
<h4 class="subject" id="4.body">4.body <a class="hashlink" href="#4.body">#</a></h4><p> 返回 response body</p>
|
||||
<h4 class="subject" id="5.header">5.header <a class="hashlink" href="#5.header">#</a></h4><p> 返回 response header</p>
|
||||
<h4 class="subject" id="6.records">6.records <a class="hashlink" href="#6.records">#</a></h4><p> 记录的 http 请求信息,假设需要获取 key 为 555 的接口参数或者响应数据,可通过 records[555].params 或 records[555].body 获取 </p>
|
||||
<h4 class="subject" id="7.log">7.log <a class="hashlink" href="#7.log">#</a></h4><p> log(message) 函数,调试时使用,log 信息仅仅在断言失败后打印 </p>
|
||||
<h4 class="subject" id="2.status">2.status <a class="hashlink" href="#2.status">#</a></h4><p>http 状态码</p>
|
||||
<h4 class="subject" id="3.params">3.params <a class="hashlink" href="#3.params">#</a></h4><p>http request params, 合并了 query 和 body</p>
|
||||
<h4 class="subject" id="4.body">4.body <a class="hashlink" href="#4.body">#</a></h4><p>返回 response body</p>
|
||||
<h4 class="subject" id="5.header">5.header <a class="hashlink" href="#5.header">#</a></h4><p>返回 response header</p>
|
||||
<h4 class="subject" id="6.records">6.records <a class="hashlink" href="#6.records">#</a></h4><p>记录的 http 请求信息,假设需要获取 key 为 555 的接口参数或者响应数据,可通过 records[555].params 或 records[555].body 获取</p>
|
||||
<h4 class="subject" id="7.log">7.log <a class="hashlink" href="#7.log">#</a></h4><p>log(message) 函数,调试时使用,log 信息仅仅在断言失败后打印</p>
|
||||
<h3 class="subject" id="示例">示例 <a class="hashlink" href="#示例">#</a></h3><pre><code>assert.equal(body.errcode<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span>
|
||||
assert.equal(body.data.group_name<span class="token punctuation">,</span> 'testGroup'<span class="token punctuation">)</span>
|
||||
assert.equal(status<span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span>
|
||||
|
BIN
static/doc/images/autoTest.png
Normal file
After Width: | Height: | Size: 65 KiB |
BIN
static/doc/images/autoTestResult.png
Normal file
After Width: | Height: | Size: 132 KiB |
BIN
static/doc/images/jsonSchema.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
static/doc/images/usage/json-schema-demo.jpg
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
static/doc/images/usage/json-schema-mock.jpg
Normal file
After Width: | Height: | Size: 148 KiB |
@ -186,7 +186,8 @@
|
||||
<li>Query参数: 接口 url 的查询字符串,点击『添加Query参数』按钮来添加参数,可以通过拖动来交换参数位置</li><li>请求Body:http 请求 body 部分,如果http请求方式是 post, put 等请求方式时会有 req_body 部分。req_body_type 形式有4种,分别是 form, json, file 和 raw 。</li><li>Headers: http 请求头字段,在 req_body 形式是 form 格式下会在 header 中自动生成 'Content-Type application/x-www-form-urlencoded',其他3种格式也会自动生成不同 header</li></ul>
|
||||
<p><img src="./images/requestSet.png" /></p>
|
||||
<h3 class="subject" id="返回数据设置">返回数据设置 <a class="hashlink" href="#返回数据设置">#</a></h3><ul>
|
||||
<li>返回数据分为 <code>json</code> & <code>raw</code> 两种形式。基于 mockjs (具体使用方法详见<a href="./mock.html">Mock 介绍</a>)和 json5,使用注释方式写参数说明。 为了方便数据编写可以按F9来使用全局编辑</li></ul>
|
||||
<li>返回数据分为 <code>json</code> & <code>raw</code> 两种形式。基于 mockjs (具体使用方法详见<a href="./mock.html">Mock 介绍</a>)和 json5,使用注释方式写参数说明。 为了方便数据编写可以按F9来使用全局编辑</li><li>选择json-schema 则进入了 json 结构可视化编辑器形式, 数据以 json schema 格式解析 <a target="_blank" href="https://www.jianshu.com/p/8278eb2458c4?winzoom=1">快速入门 Json Schema </a>。</li></ul>
|
||||
<p><img src="./images/jsonSchema.png" /></p>
|
||||
<h3 class="subject" id="备注_&_其他">备注 & 其他 <a class="hashlink" href="#备注_&_其他">#</a></h3><ul>
|
||||
<li>接口描述: 用简短的文字描述接口的作用。</li><li>邮件通知:开启后将此次接口的改动以邮件的形式发送至项目组所有成员和关注该项目的成员(邮件默认情况下自动开启)</li><li>开放接口:默认为关闭状态,用户可以在 数据导出 时选择只导出公开接口</li></ul>
|
||||
<h2 class="subject" id="接口运行">接口运行 <a class="hashlink" href="#接口运行">#</a></h2><p>接口运行功能,是用来测试真实接口的,类似『Postman』的功能。</p>
|
||||
|
@ -149,15 +149,11 @@
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="#原理">原理</a>
|
||||
<a href="#方式1._json-schema">方式1. json-schema</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="#如何使用_Mock">如何使用 Mock</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="#Mock_语法规范">Mock 语法规范</a>
|
||||
<a href="#方式2._json5+注释">方式2. json5+注释</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
@ -195,11 +191,13 @@
|
||||
<p>注:项目 id 可以在项目设置里查看到</p>
|
||||
</blockquote>
|
||||
<h2 class="subject" id="定义_mock_数据示例">定义 mock 数据示例 <a class="hashlink" href="#定义_mock_数据示例">#</a></h2><p>项目 -> 接口编辑 -> 返回数据设置</p>
|
||||
<p><img src="./images/usage/mock-demo.jpg" /></p>
|
||||
<blockquote>
|
||||
<p>注:开启 json-schema 功能后,将不再使用 mockjs 解析定义的返回数据,而是根据 json-schema 定义的数据结构,生成随机数据。</p>
|
||||
</blockquote>
|
||||
<h2 class="subject" id="原理">原理 <a class="hashlink" href="#原理">#</a></h2><p>YApi Mock 功能基于 node 和 <a href="http://mockjs.com">mockjs</a>,跟 Mockjs 区别是 yapi 基于 json 定义 mock ,无法使用 mockjs 原有的函数功能,正则表达式需要基于 rule 书写,示例如下:</p>
|
||||
<p>返回数据设置有两种方式,最新版本默认是基于 <code>json-schema</code> 定义数据结构,另外一种是基于 <code>json+注释</code> 的方式,请根据实际情况灵活选择使用。</p>
|
||||
<h2 class="subject" id="方式1._json-schema">方式1. json-schema <a class="hashlink" href="#方式1._json-schema">#</a></h2><p><img src="./images/usage/json-schema-demo.jpg" /></p>
|
||||
<p>开启 json-schema 功能后,将不再使用 mockjs 解析定义的返回数据,而是根据 json-schema 定义的数据结构,生成随机数据。</p>
|
||||
<h3 class="subject" id="如何生成随机的邮箱或_ip?">如何生成随机的邮箱或 ip? <a class="hashlink" href="#如何生成随机的邮箱或_ip?">#</a></h3><p><img src="./images/usage/json-schema-mock.jpg" /></p>
|
||||
<p>点击高级设置,选择 <code>format</code> 选项,比如选择 <code>email</code> 则该字段生成随机邮箱字符串。</p>
|
||||
<h2 class="subject" id="方式2._json5+注释">方式2. json5+注释 <a class="hashlink" href="#方式2._json5+注释">#</a></h2><p><img src="./images/usage/mock-demo.jpg" /></p>
|
||||
<h3 class="subject" id="原理">原理 <a class="hashlink" href="#原理">#</a></h3><p>YApi Mock 功能基于 node 和 <a href="http://mockjs.com">mockjs</a>,跟 Mockjs 区别是 yapi 基于 json 定义 mock ,无法使用 mockjs 原有的函数功能,正则表达式需要基于 rule 书写,示例如下:</p>
|
||||
<pre><code><span class="token punctuation">{</span>
|
||||
<span class="token property">"name|regexp"</span><span class="token operator">:</span> <span class="token string">"[a-z0-9_]+?"</span><span class="token punctuation">,</span>
|
||||
<span class="token property">"type|regexp"</span><span class="token operator">:</span> <span class="token string">"json|text|xml"</span> //枚举数据类型可这样实现
|
||||
@ -210,31 +208,31 @@
|
||||
<span class="token property">"type"</span><span class="token operator">:</span> <span class="token string">"${body.type}"</span> //请求的requestBody type=<span class="token number">1</span><span class="token punctuation">,</span>返回的type字段是<span class="token number">1</span>
|
||||
<span class="token punctuation">}</span>
|
||||
</code></pre><p>其他基本用法请查看:<a href="http://mockjs.com/examples.html">Mockjs 官网</a></p>
|
||||
<h2 class="subject" id="如何使用_Mock">如何使用 Mock <a class="hashlink" href="#如何使用_Mock">#</a></h2><h3 class="subject" id="1_在_js_代码直接请求yapi提供的_mock_地址(不用担心跨域问题)">1 在 js 代码直接请求yapi提供的 mock 地址(不用担心跨域问题) <a class="hashlink" href="#1_在_js_代码直接请求yapi提供的_mock_地址(不用担心跨域问题)">#</a></h3><p>在代码直接请求 yapi 提供的 mock 地址,以 jQuery 为例:</p>
|
||||
<h3 class="subject" id="如何使用_Mock">如何使用 Mock <a class="hashlink" href="#如何使用_Mock">#</a></h3><h4 class="subject" id="1_在_js_代码直接请求yapi提供的_mock_地址(不用担心跨域问题)">1 在 js 代码直接请求yapi提供的 mock 地址(不用担心跨域问题) <a class="hashlink" href="#1_在_js_代码直接请求yapi提供的_mock_地址(不用担心跨域问题)">#</a></h4><p>在代码直接请求 yapi 提供的 mock 地址,以 jQuery 为例:</p>
|
||||
<pre><code class="lang-javascript"><span class="token keyword">let</span> prefix <span class="token operator">=</span> <span class="token string">'http://yapi.xxx.com/mock/2817'</span>
|
||||
$<span class="token punctuation">.</span><span class="token function">post</span><span class="token punctuation">(</span>prefix<span class="token operator">+</span><span class="token string">'/baseapi/path'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>username<span class="token punctuation">:</span> <span class="token string">'xxx'</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">{</span>
|
||||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token comment">//返回上图预览部分的数据</span>
|
||||
<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
</code></pre>
|
||||
<h3 class="subject" id="2_基于本地服务器反向代理">2 基于本地服务器反向代理 <a class="hashlink" href="#2_基于本地服务器反向代理">#</a></h3><p>优点:不用修改项目代码</p>
|
||||
<h4 class="subject" id="2.1_基于_nginx_反向代理">2.1 基于 nginx 反向代理 <a class="hashlink" href="#2.1_基于_nginx_反向代理">#</a></h4><pre><code class="lang-nginx"><span class="token keyword">location</span> <span class="token operator">/</span>baseapi
|
||||
<h4 class="subject" id="2_基于本地服务器反向代理">2 基于本地服务器反向代理 <a class="hashlink" href="#2_基于本地服务器反向代理">#</a></h4><p>优点:不用修改项目代码</p>
|
||||
<h5 class="subject" id="2.1_基于_nginx_反向代理">2.1 基于 nginx 反向代理 <a class="hashlink" href="#2.1_基于_nginx_反向代理">#</a></h5><pre><code class="lang-nginx"><span class="token keyword">location</span> <span class="token operator">/</span>baseapi
|
||||
<span class="token punctuation">{</span>
|
||||
<span class="token keyword">proxy_pass</span> <span class="token keyword">http</span><span class="token punctuation">:</span><span class="token operator">/</span><span class="token operator">/</span>yapi<span class="token punctuation">.</span>xxx<span class="token punctuation">.</span>com<span class="token operator">/</span>mock<span class="token operator">/</span><span class="token number">2817</span><span class="token operator">/</span>baseapi<span class="token punctuation">;</span> <span class="token comment">#baseapi后面没有"/"</span>
|
||||
<span class="token punctuation">}</span>
|
||||
</code></pre>
|
||||
<h4 class="subject" id="2.2_基于_ykit_mock功能">2.2 基于 ykit mock功能 <a class="hashlink" href="#2.2_基于_ykit_mock功能">#</a></h4><pre><code class="lang-javascript"><span class="token punctuation">{</span>
|
||||
<h5 class="subject" id="2.2_基于_ykit_mock功能">2.2 基于 ykit mock功能 <a class="hashlink" href="#2.2_基于_ykit_mock功能">#</a></h5><pre><code class="lang-javascript"><span class="token punctuation">{</span>
|
||||
pattern<span class="token punctuation">:</span> <span class="token regex">/\/api\/(.*)/</span><span class="token punctuation">,</span>
|
||||
responder<span class="token punctuation">:</span> <span class="token string">'http://yapi.xxx.com/mock/58/api/$1'</span>
|
||||
<span class="token punctuation">}</span>
|
||||
</code></pre>
|
||||
<p>上面通过正则匹配,将所有接口转到 <a href="http://yapi.xxx.com">http://yapi.xxx.com</a> 上,比如 <code>http://localhost/api/user/status</code> 会成为 <code>http://yapi.xxx.com/mock/58/api/user/status</code></p>
|
||||
<p>详细使用指南: <a target="_blank" href="https://ykit.ymfe.org/plugins-mock.html#获取远程数据_Map_Remote_">ykit-config-mock</a></p>
|
||||
<h4 class="subject" id="2.3_基于_ykit_Jerry_代理">2.3 基于 ykit Jerry 代理 <a class="hashlink" href="#2.3_基于_ykit_Jerry_代理">#</a></h4><p>假设您本地服务器访问地址是: <a href="http://xxx.com">http://xxx.com</a></p>
|
||||
<h5 class="subject" id="2.3_基于_ykit_Jerry_代理">2.3 基于 ykit Jerry 代理 <a class="hashlink" href="#2.3_基于_ykit_Jerry_代理">#</a></h5><p>假设您本地服务器访问地址是: <a href="http://xxx.com">http://xxx.com</a></p>
|
||||
<p><img src="./images/ykit.jpg" /></p>
|
||||
<p><span id="mock"></span></p>
|
||||
<h4 class="subject" id="2.4_基于_Charles_代理">2.4 基于 Charles 代理 <a class="hashlink" href="#2.4_基于_Charles_代理">#</a></h4><p>点击 Charles 工具栏下的 tools >> Rewrite Settings 填写如下信息:</p>
|
||||
<h5 class="subject" id="2.4_基于_Charles_代理">2.4 基于 Charles 代理 <a class="hashlink" href="#2.4_基于_Charles_代理">#</a></h5><p>点击 Charles 工具栏下的 tools >> Rewrite Settings 填写如下信息:</p>
|
||||
<p><img src="./images/charles.png" width="60%" /></p>
|
||||
<h2 class="subject" id="Mock_语法规范">Mock 语法规范 <a class="hashlink" href="#Mock_语法规范">#</a></h2><blockquote>
|
||||
<h3 class="subject" id="Mock_语法规范">Mock 语法规范 <a class="hashlink" href="#Mock_语法规范">#</a></h3><blockquote>
|
||||
<p>了解更多Mock详情:<a href="http://mockjs.com/examples.html">Mock.js 官方文档</a></p>
|
||||
</blockquote>
|
||||
<p>Mock.js 的语法规范包括两部分:</p>
|
||||
@ -257,14 +255,14 @@ $<span class="token punctuation">.</span><span class="token function">post</span
|
||||
'name|count.dcount'<span class="token operator">:</span> value
|
||||
'name|+step'<span class="token operator">:</span> value
|
||||
</code></pre><p>下面提供了6种生成规则以及示例包括 String、Number、Boolean、Object、Array:</p>
|
||||
<h3 class="subject" id="1._属性值是字符串_String">1. 属性值是字符串 String <a class="hashlink" href="#1._属性值是字符串_String">#</a></h3><pre><code><span class="token number">1</span>. 'name|min-max'<span class="token operator">:</span> string
|
||||
<h4 class="subject" id="1._属性值是字符串_String">1. 属性值是字符串 String <a class="hashlink" href="#1._属性值是字符串_String">#</a></h4><pre><code><span class="token number">1</span>. 'name|min-max'<span class="token operator">:</span> string
|
||||
|
||||
通过重复 string 生成一个字符串,重复次数大于等于 min,小于等于 max。
|
||||
|
||||
<span class="token number">2</span>. 'name|count'<span class="token operator">:</span> string
|
||||
|
||||
通过重复 string 生成一个字符串,重复次数等于 count。
|
||||
</code></pre><h3 class="subject" id="2._属性值是数字_Number">2. 属性值是数字 Number <a class="hashlink" href="#2._属性值是数字_Number">#</a></h3><pre><code><span class="token number">1</span>. 'name|+<span class="token number">1</span>'<span class="token operator">:</span> number
|
||||
</code></pre><h4 class="subject" id="2._属性值是数字_Number">2. 属性值是数字 Number <a class="hashlink" href="#2._属性值是数字_Number">#</a></h4><pre><code><span class="token number">1</span>. 'name|+<span class="token number">1</span>'<span class="token operator">:</span> number
|
||||
|
||||
属性值自动加 <span class="token number">1</span>,初始值为 number。
|
||||
|
||||
@ -290,21 +288,21 @@ Mock.mock(<span class="token punctuation">{</span>
|
||||
<span class="token property">"number3"</span><span class="token operator">:</span> <span class="token number">123.777</span><span class="token punctuation">,</span>
|
||||
<span class="token property">"number4"</span><span class="token operator">:</span> <span class="token number">123.1231091814</span>
|
||||
<span class="token punctuation">}</span>
|
||||
</code></pre><h3 class="subject" id="3._属性值是布尔型_Boolean">3. 属性值是布尔型 Boolean <a class="hashlink" href="#3._属性值是布尔型_Boolean">#</a></h3><pre><code><span class="token number">1</span>. 'name|<span class="token number">1</span>'<span class="token operator">:</span> boolean
|
||||
</code></pre><h4 class="subject" id="3._属性值是布尔型_Boolean">3. 属性值是布尔型 Boolean <a class="hashlink" href="#3._属性值是布尔型_Boolean">#</a></h4><pre><code><span class="token number">1</span>. 'name|<span class="token number">1</span>'<span class="token operator">:</span> boolean
|
||||
|
||||
随机生成一个布尔值,值为 <span class="token boolean">true</span> 的概率是 <span class="token number">1</span>/<span class="token number">2</span>,值为 <span class="token boolean">false</span> 的概率同样是 <span class="token number">1</span>/<span class="token number">2</span>。
|
||||
|
||||
<span class="token number">2</span>. 'name|min-max'<span class="token operator">:</span> value
|
||||
|
||||
随机生成一个布尔值,值为 value 的概率是 min / (min + max<span class="token punctuation">)</span>,值为 !value 的概率是 max / (min + max<span class="token punctuation">)</span>。
|
||||
</code></pre><h3 class="subject" id="4._属性值是对象_Object">4. 属性值是对象 Object <a class="hashlink" href="#4._属性值是对象_Object">#</a></h3><pre><code><span class="token number">1</span>. 'name|count'<span class="token operator">:</span> object
|
||||
</code></pre><h4 class="subject" id="4._属性值是对象_Object">4. 属性值是对象 Object <a class="hashlink" href="#4._属性值是对象_Object">#</a></h4><pre><code><span class="token number">1</span>. 'name|count'<span class="token operator">:</span> object
|
||||
|
||||
从属性值 object 中随机选取 count 个属性。
|
||||
|
||||
<span class="token number">2</span>. 'name|min-max'<span class="token operator">:</span> object
|
||||
|
||||
从属性值 object 中随机选取 min 到 max 个属性。
|
||||
</code></pre><h3 class="subject" id="5._属性值是数组_Array">5. 属性值是数组 Array <a class="hashlink" href="#5._属性值是数组_Array">#</a></h3><pre><code><span class="token number">1</span>. 'name|<span class="token number">1</span>'<span class="token operator">:</span> array
|
||||
</code></pre><h4 class="subject" id="5._属性值是数组_Array">5. 属性值是数组 Array <a class="hashlink" href="#5._属性值是数组_Array">#</a></h4><pre><code><span class="token number">1</span>. 'name|<span class="token number">1</span>'<span class="token operator">:</span> array
|
||||
|
||||
从属性值 array 中随机选取 <span class="token number">1</span> 个元素,作为最终值。
|
||||
|
||||
@ -320,7 +318,7 @@ Mock.mock(<span class="token punctuation">{</span>
|
||||
|
||||
通过重复属性值 array 生成一个新数组,重复次数为 count。
|
||||
</code></pre><p><span id = "DPD"></span></p>
|
||||
<h3 class="subject" id="数据占位符定义规范(Data_Placeholder_Definition,DPD)">数据占位符定义规范(Data Placeholder Definition,DPD) <a class="hashlink" href="#数据占位符定义规范(Data_Placeholder_Definition,DPD)">#</a></h3><pre><code>占位符 只是在属性值字符串中占个位置,并不出现在最终的属性值中。
|
||||
<h4 class="subject" id="数据占位符定义规范(Data_Placeholder_Definition,DPD)">数据占位符定义规范(Data Placeholder Definition,DPD) <a class="hashlink" href="#数据占位符定义规范(Data_Placeholder_Definition,DPD)">#</a></h4><pre><code>占位符 只是在属性值字符串中占个位置,并不出现在最终的属性值中。
|
||||
|
||||
占位符 的格式为:
|
||||
|
||||
|
@ -150,14 +150,14 @@
|
||||
|
||||
<div class="content-right markdown-body use-sidebar" role="main">
|
||||
|
||||
<h2 class="subject" id="后端_hookList">后端 hookList <a class="hashlink" href="#后端_hookList">#</a></h2><p>目前 hooksList 只有下面列出的部分,如果您有其他的需求,可提建议到 github 或者 qq群</p>
|
||||
<h2 class="subject" id="后端_hookList">后端 hookList <a class="hashlink" href="#后端_hookList">#</a></h2><p>目前 hooksList 只有下面列出的部分,如果您有其他的需求,可提建议到 github 或者 qq 群</p>
|
||||
<pre><code>/**
|
||||
* 钩子配置
|
||||
*/
|
||||
var hooks = <span class="token punctuation">{</span>
|
||||
/**
|
||||
* 第三方sso登录钩子,暂只支持设置一个
|
||||
* @param ctx
|
||||
* @param ctx
|
||||
* @return 必需返回一个 promise 对象,resolve(<span class="token punctuation">{</span>username<span class="token operator">:</span> ''<span class="token punctuation">,</span> email<span class="token operator">:</span> ''<span class="token punctuation">}</span><span class="token punctuation">)</span>
|
||||
*/
|
||||
'third_login'<span class="token operator">:</span> <span class="token punctuation">{</span>
|
||||
@ -227,9 +227,9 @@ var hooks = <span class="token punctuation">{</span>
|
||||
* projectData<span class="token operator">:</span> project<span class="token punctuation">,</span>
|
||||
interfaceData<span class="token operator">:</span> interfaceData<span class="token punctuation">,</span>
|
||||
ctx<span class="token operator">:</span> ctx<span class="token punctuation">,</span>
|
||||
mockJson<span class="token operator">:</span> res
|
||||
mockJson<span class="token operator">:</span> res
|
||||
* <span class="token punctuation">}</span>
|
||||
*
|
||||
*
|
||||
*/
|
||||
mock_after<span class="token operator">:</span> <span class="token punctuation">{</span>
|
||||
type<span class="token operator">:</span> 'multi'<span class="token punctuation">,</span>
|
||||
@ -238,7 +238,7 @@ var hooks = <span class="token punctuation">{</span>
|
||||
/**
|
||||
* 增加路由的钩子
|
||||
* type Sync
|
||||
* @param addPluginRouter Function
|
||||
* @param addPluginRouter Function
|
||||
* addPLuginPLugin(config<span class="token punctuation">)</span>
|
||||
* config = <span class="token punctuation">{</span>
|
||||
* path<span class="token punctuation">,</span> // String
|
||||
@ -256,7 +256,7 @@ var hooks = <span class="token punctuation">{</span>
|
||||
* type component 组件
|
||||
* listener 监听函数
|
||||
* mulit 是否绑定多个监听函数
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
hooks = <span class="token punctuation">{</span>
|
||||
@ -273,7 +273,7 @@ hooks = <span class="token punctuation">{</span>
|
||||
* @param Object exportDataModule
|
||||
* @param projectId
|
||||
* @info
|
||||
* exportDataModule = <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||||
* exportDataModule = <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||||
* exportDataModule.pdf = <span class="token punctuation">{</span>
|
||||
* name<span class="token operator">:</span> 'Pdf'<span class="token punctuation">,</span>
|
||||
* route<span class="token operator">:</span> '/api/plugin/export/pdf'<span class="token punctuation">,</span>
|
||||
@ -288,11 +288,11 @@ hooks = <span class="token punctuation">{</span>
|
||||
/**
|
||||
* 导入数据
|
||||
* @param importDataModule
|
||||
*
|
||||
*
|
||||
* @info
|
||||
* 可参考 vendors/exts/yapi-plugin-import-swagger插件
|
||||
* importDataModule = <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||||
*
|
||||
* importDataModule = <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
|
||||
*
|
||||
*/
|
||||
import_data<span class="token operator">:</span> <span class="token punctuation">{</span>
|
||||
type<span class="token operator">:</span> 'listener'<span class="token punctuation">,</span>
|
||||
@ -302,7 +302,7 @@ hooks = <span class="token punctuation">{</span>
|
||||
/**
|
||||
* 接口页面 tab 钩子
|
||||
* @param InterfaceTabs
|
||||
*
|
||||
*
|
||||
* @info
|
||||
* 可参考 vendors/exts/yapi-plugin-advanced-mock
|
||||
* let InterfaceTabs = <span class="token punctuation">{</span>
|
||||
|
@ -147,6 +147,10 @@
|
||||
<li >
|
||||
<a href="#请求配置">请求配置</a>
|
||||
</li>
|
||||
|
||||
<li >
|
||||
<a href="#token配置">token配置</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -267,7 +271,8 @@
|
||||
sha512 //转换字符串为 sha512 编码
|
||||
unbase64 //转换 base64 编码为字符串
|
||||
<span class="token punctuation">}</span>
|
||||
</code></pre>
|
||||
</code></pre><h2 class="subject" id="token配置">token配置 <a class="hashlink" href="#token配置">#</a></h2><p>每个项目都有唯一的标识token,用户可以使用这个token值来请求项目的所有资源数据。目前用到的地方是接口的<a href="./case.html">自动化测试</a>,用户不需要登录就可以访问接口测试结果信息。</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|