UNPKG

yapi-plugin-auto-test

Version:

YAPI自动化测试插件,支持在YAPI设置测试计划,查看历史测试结果,自定义通知。

151 lines (135 loc) 4.9 kB
const schedule = require('node-schedule'); const planModel = require('./models/plan'); const resultModel = require('./models/result'); const yapi = require('yapi.js'); const axios = require('axios'); const jobMap = new Map(); const retryMap = new Map(); /** * 定时执行测试计划 */ class testSchedule { constructor(ctx) { this.ctx = ctx; this.planModel = yapi.getInst(planModel); this.resultModel = yapi.getInst(resultModel); this.init() } //初始化定时任务 async init() { let allPlan = await this.planModel.listAll(); for (let i = 0, len = allPlan.length; i < len; i++) { let plan = allPlan[i]; if (plan.is_plan_open) { this.addTestJob(plan._id, plan); } } } /** * 添加一个测试计划 * @param {测试计划id} planId * @param {测试计划} plan */ async addTestJob(planId, plan) { var url = plan.plan_url; // 自动测试不支持下载 url = url.replace("download=true", "download=false"); url = url.replace("mode=html", "mode=json"); // 清空url中带的plan_id url = url.replace(/&plan_id=\d+&/, "&") // 替换API url = url.replace("/api/open/run_auto_test", "/api/open/plugin/test/run"); url += "&plan_id=" + planId; let handlerPlan = async (planId, plan, retry) => { try { let result = await axios.get(url); let data = result.data || { message: {} }; this.saveTestLog(plan.plan_name, data.message.msg, plan.uid, plan.project_id); if (plan.plan_result_size >= 0) { let results = await this.resultModel.findByPlan(planId); let ids = results.map((val) => val._id).slice(plan.plan_result_size); await this.resultModel.deleteByIds(ids); } let job = jobMap.get(planId); if (data.message.failedNum !== 0 && plan.plan_fail_retries && plan.plan_fail_retries > retry) { job && job.cancel(); let retryDate = new Date(); let seconds = retryDate.getSeconds(); retryDate.setSeconds(seconds + 60 * (retry + 1)); // 延迟60 * 次数s执行重试 let retryItem = schedule.scheduleJob(retryDate, async () => { yapi.commons.log(`项目ID为【${plan.project_id}】下测试计划【${plan.plan_name}】失败后自动重试第${retry+1}次`); this.deleteRetryJob(planId); // 开始执行就取消重试的任务防止重复执行 await handlerPlan(planId, plan, retry + 1); }); this.addRetryJob(planId, retryItem) } else if (retry > 0) { // 重试过的任务不再重试就需要恢复 job && job.reschedule(plan.plan_cron); } } catch (e) { yapi.commons.log(`项目ID为【${plan.project_id}】下测试计划【${plan.plan_name}】配置有误,请检查后重新配置。`); } } let scheduleItem = schedule.scheduleJob(plan.plan_cron, async () => { handlerPlan(planId, plan, 0); }); //判断是否已经存在这个任务 let jobItem = jobMap.get(planId); if (jobItem) { jobItem.cancel(); } jobMap.set(planId, scheduleItem); } /** * 获取测试计划 * @param {测试计划id} planId */ getTestJob(planId) { return jobMap.get(planId); } /** * 删除测试计划 * @param {测试计划id} planId */ deleteTestJob(planId) { let jobItem = jobMap.get(planId); if (jobItem) { jobItem.cancel(); } this.deleteRetryJob(planId); } // 动态中添加测试结果 saveTestLog(plan, msg, uid, projectId) { yapi.commons.saveLog({ content: `成功执行计划名为"${plan}"的自动化测试,${msg}。`, type: 'project', uid: uid, username: "自动化测试", typeid: projectId }); } /** * 添加重试计划 * @param {*} planId * @param {*} retryItem */ addRetryJob(planId, retryItem) { let jobItem = retryMap.get(planId); if (jobItem) { jobItem.cancel(); } retryMap.set(planId, retryItem) } /** * 删除重试计划 * @param {测试计划id} planId */ deleteRetryJob(planId) { let jobItem = retryMap.get(planId); if (jobItem) { jobItem.cancel(); } } } module.exports = testSchedule;