基于设计思路2,实现动态加载
src/util/save_extract.js
提取数据,把数据保存于map中
const type_judge = require('../utils/type_judge');
const {ParameterError} = require('../utils/error')
/**
* @description 从obj中提取字段名为str的字段及其值
* @param {string} str 要提取的字符串,case中需要提取的值
* @param {object|string} obj 待提取的对象,response或者request
* @param {number} index 如果提取的是字段位于数组中,默认提取0下标的值
* @param {object} robj 返回值,初始化空对象
* @return {{robj}} 被提取的值会以对象形式返回
*/
function extract(str, obj, index = 0, robj = {}) {
let temp
if (type_judge(obj) === 'String') {
temp = JSON.parse(obj)
} else {
temp = obj
}
for (let i in temp) {
if (type_judge(temp[i]) === 'Array' && str === i) {
robj[i] = temp[i][index]
} else if (type_judge(temp[i]) === 'Object' && str !== i) {
extract(str, temp[i], index, robj)
} else if (type_judge(temp[i]) === 'Object' && str === i) {
throw ParameterError('The parameter you need to match should not be an object')
} else if (str === i && type_judge(temp[i]) === 'String') {
robj[i] = temp[i]
}
}
return robj
}
function saveExtract(obj, objReq, objRes, map) {
if (obj.hasOwnProperty('isExtract')) {
let elementsRes = [];
let elementsReq = [];
switch (obj['isExtract']) {
case 1:
if (obj.hasOwnProperty('req_extract')) {
obj['req_extract'].forEach(function (element) {
elementsReq.push(element)
})
} else {
throw new ParameterError(`${JSON.stringify(obj)}:missing 'req_extract' field`)
}
break
case 2:
if (obj.hasOwnProperty('res_extract')) {
obj['res_extract'].forEach(function (element) {
elementsRes.push(element)
})
} else {
throw new ParameterError(`${JSON.stringify(obj)}:missing 'res_extract' field`)
}
break
case 3:
if (obj.hasOwnProperty('req_extract')) {
obj['req_extract'].forEach(function (element) {
elementsReq.push(element)
})
}
if (obj.hasOwnProperty('res_extract')) {
obj['res_extract'].forEach(function (element) {
elementsRes.push(element)
})
} else
throw new ParameterError(`${JSON.stringify(obj)}:The parmas of res_extract or req_extract is incorrect`)
break
default:
throw new ParameterError(`${JSON.stringify(obj)}:The value of isExtract is incorrect`)
}
for (let i in elementsReq) {
if (obj.hasOwnProperty('as')) {
for (let k in obj['as']) {
if (elementsReq[i] === k) {
map.set(obj['as'][k], extract(elementsReq[i], objReq)[elementsReq[i]])
}
}
} else {
map.set(elementsReq[i], extract(elementsReq[i], objReq)[elementsReq[i]])
}
}
for (let i in elementsRes) {
if (obj.hasOwnProperty('as')) {
for (let k in obj['as']) {
if (elementsRes[i] === k) {
map.set(obj['as'][k], extract(elementsRes[i], objRes)[elementsRes[i]])
}
}
} else {
map.set(elementsRes[i], extract(elementsRes[i], objRes)[elementsRes[i]])
}
}
}
return map
}
module.exports = saveExtract
src/replace_config.js
替换引用字段
const setting = require('../config/global/defaults')
/**
* @description 正则匹配并替换引用
* @param {object}obj
* @param map
* @return {object}返回替换后的对象||原对象
*/
async function replaceQuote(obj, map) {
for (let i in setting.replace_setting) {
let quoteList = []
if (obj.hasOwnProperty(setting.replace_setting[i])) {
if (obj[setting.replace_setting[i]] !== null) {
quoteList = obj[setting.replace_setting[i]].match(/(?<={)(\w+)(?=})/g)
if (quoteList !== null) {
for (let j in quoteList) {
if (map.has(quoteList[j])) {
console.log(typeof obj[setting.replace_setting[i]])
obj[setting.replace_setting[i]] = obj[setting.replace_setting[i]].replace(`{${quoteList[j]}}`, map.get(quoteList[j]))
}
}
}
}
} else if (obj['config'].hasOwnProperty(setting.replace_setting[i])) {
if (obj['config'][setting.replace_setting[i]] !== null) {
quoteList = JSON.stringify(obj['config'][setting.replace_setting[i]]).match(/(?<={)(\w+)(?=})/g)
if (quoteList !== null) {
for (let k in quoteList) {
if (map.has(quoteList[k])) {
obj['config'][setting.replace_setting[i]] = JSON.parse(JSON.stringify(obj['config'][setting.replace_setting[i]]).replace(`{${quoteList[k]}}`, map.get(quoteList[k])))
}
}
}
}
}
}
return obj
}
module.exports = replaceQuote
src/api/list/test.js
const compare = require('../../utils/compare');
const request = require('../../utils/request')
const before = require('../../config/global/before');
const saveExtract = require('../../utils/save_extract');
const assert = require('assert')
const replaceQuote = require('../../utils/replace_config')
const file_load = require('../../utils/file_load')
const path = require('path')
describe('api', function () {
let case_path = 'src/config/case'
let files = file_load(case_path)
let mapGlobal = new Map()
beforeAll(async () => {
await before().then(res => {
mapGlobal.set('cookie', res)
mapGlobal.set('content-type', 'application/json;charset=UTF-8')
})
});
beforeEach(async () => {
});
/**
* @description: 循环执行每个用例
*/
for (let j = 0; j < files.length; j++) {
let mapLocal = new Map()
let module_name = files[j].replace('.js', '')
let module_path = path.join('../../config/case', module_name)
let module_list = {}
module_list[module_name] = require(module_path)
for (let i in module_list[module_name]) {
let t = module_list[module_name][i].name === '' ? undefined : module_list[module_name][i].name
let name = t ?? module_list[module_name][i].config.url
it(`${name}`, async function () {
let requestConfig = await replaceQuote(module_list[module_name][i], mapLocal)
module_list[module_name][i].config.headers['Cookie'] = mapGlobal.get('cookie')
module_list[module_name][i].config.headers['Content-Type'] = mapGlobal.get('content-type')
await request(requestConfig.config).then(res => {
saveExtract(module_list[module_name][i], res.config.data, res.data, mapLocal)
compare(module_list[module_name][i], res.data)
}).catch(
err => assert.fail(err)
)
});
}
}
afterEach(function () {
})
afterAll(function () {
})
})
src/config/global/defaults.js
/**
* @description 公钥
*/
exports.pubkey = 'xxx';
/**
* @param {object} user
* @description username:用户名,password:密码
*/
exports.user = {
username: 'user',
password: 'xxxx'
}
exports.baseUrl = 'http://xxxx.com/'
exports.targetUrl = 'http://xxxc.com'
/**
* @description orderList表示任务运行时的执行顺序,最好和case的文件数量保持一致
*/
exports.orderList = [
'homepage_case',
'keyword_case',
'regular_case',
'task_case'
]
/**
* @description 配置case中,需要去替换引用的字段
*/
exports.replace_setting = ["url", "data", "params", "name"]
src/config/case/task_case.js
const pathList = require('../global/path')
const data = require('../data/task')
/**
* @description isExtract:1 提取reqest,2提取response,3 提取request和response
* @description as:被提取字段的别名
*/
module.exports = [
{
isExtract: 2,
name: 'keyword',
config: {
url: pathList.keywordPathList.save,
method: 'post',
headers: {},
data: data.keyword
},
assert: [{code: '0000'}, {msg: '执行成功'}],
res_extract: ['data'],
as: {
data: 'id'
}
},
]
6、只要执行test.js一个文件,便能对case下的文件进行测试了,新增接口也只需要新建个case文件,按照数据接口配置即可