通过前三章学习,这一章来和大家一起实现一个自动化测试的小例子
思路是想通过网页端,点击一个按钮来实现自动化测试,希望能有每一步测试的进度和状态如图所示:
大概思路就是这样,下面开始实现这个例子。
前期准备
后端接口
在上一章中已经实现了一个 /pins 接口这里我们想要点击按钮进行测试,需要实现两个两个接口,一个 /home 接口,用来登录判断首页状态, 一个 /checklist 接口用来判断沸点的发布状态。 生成 home.js ,checklist.js 放到 puppeteer目录下
const express = require('express')
const start = require('./puppeteer/pins')
const checklist = require('./puppeteer/checklist')
const home = require('./puppeteer/home')
const app = express()
app.get('/home', async function (req, res) {
const homeStatus = await home().catch(err => {
res.send(err)
})
res.send(homeStatus)
})
app.get('/pins', async function (req, res) {
const pins = await start()
res.send(pins)
})
app.get('/checklist', async function (req, res) {
const checklistStatus = await checklist().catch(err => {
res.send(err)
})
res.send(checklistStatus)
})
app.listen(3000)
这样两个接口就准备好了
puppeteer脚本实现
home
首先实现home脚本,笔记简单做一个登录即可
const puppeteer = require("puppeteer");
const cookieObjects = require('./cookie');
async function home() {
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 800
}); // 设置浏览器视窗大小
cookieObjects.forEach((cookie) => {
page.setCookie(cookie);
});
await page.goto("https://juejin.cn", {
waitUntil: 'networkidle0'
});
return true
}
module.exports = home
- cookie是上一章中和大家一起导出的cookie.js
- headless: false可以不加,现在打开是为了好看而已
- waitUntil: 'networkidle0' 等待接口都加载完 这样页面数据就ok了
这里简单的返回了一个true用来做状态
checkList
checkList我们也让他返回一个true来做成功状态判断,checkList除了登录之外还有其他操作:
- 等待页面跳转完成
- 等待某个元素出现
- 输入沸点内容
- 点击按钮进行提交
- 监听接口,根据返回值来判断状态
const puppeteer = require("puppeteer");
const cookieObjects = require('./cookie');
async function checkList() {
const browser = await puppeteer.launch({
headless: false
});
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 800
}); // 设置浏览器视窗大小
cookieObjects.forEach((cookie) => {
page.setCookie(cookie);
});
// 5. 监听接口,根据返回值来判断状态
function getResponseBody(resolve, reject){
page.on('response',async (response) => {
if (['xhr', 'fetch'].includes(response.request().resourceType())) {
if (response.url().indexOf('/short_msg/publish') >= 0) {
if (response.ok()) {
let body = await response.json()
console.log(body)
if (body.err_msg !== 'success') {
reject(body)
} else {
resolve(true)
}
}
reject(false)
}
}
})
}
// 5. 监听接口,根据返回值来判断状态
waitForResponse = new Promise(getResponseBody)
// 1. 等待页面跳转完成
await page.goto("https://juejin.cn/pins", {
waitUntil: 'networkidle0' // 接口都加载完 这样页面数据就ok了
});
// await page.content()
// 进入新鲜事
const newBtn = '#juejin > div.view-container.pin_container > main > main > div.dock.shadow > nav > div:nth-child(4) > div > a:nth-child(1)'
// 2. 等待某个元素出现
await page.waitForSelector(newBtn)
const [response] = await Promise.all([
page.waitForNavigation(),
page.click(newBtn),
]);
const inputSel = '.auth-card > div'
// 3. 输入沸点内容
await page.type(inputSel, 'hi')
const submitBtn = '.submit > button'
// 4. 点击按钮进行提交
await page.click(submitBtn)
// 5. 监听接口,根据返回值来判断状态
return waitForResponse
}
module.exports = checkList
- 注意第五步,分为了三步来做的,首先用
page.on('response', fn)进行请求的监听,然后把他包装成一个Promise, 最后将他返回给接口。 - 使用
await Promise.all([ page.waitForNavigation(), page.click(newBtn), ]);来实现等待点击a标签的跳转 - 这里还是将true作为返回值唯一正确判断,小伙伴们可以自己修改返回值,或者将返回值原样返回用来展示信息。
ui界面实现
上一章已经实现了一个沸点的展示,在此基础上我们增加一些代码:
<div class="pins-steps">
<a-button type="primary" @click="clickCheckListHandle">开始测试</a-button>
<div class="step-list-box">
<a-steps :current="currentStep" size="small" :status="stepsStatus">
<a-step title="开始"></a-step>
<a-step title="首页测试">
<template #icon v-if="currentStep === 1 && stepsStatus !== 'error'">
<loading-outlined />
</template>
</a-step>
<a-step title="发布沸点测试" >
<template #icon v-if="currentStep === 2 && stepsStatus !== 'error'">
<loading-outlined />
</template>
</a-step>
</a-steps>
</div>
</div>
...
// 主要代码
async getHomeStatus() {
const homeStatus = await axios.get('/api/home')
return homeStatus.data === true
},
async getPinsStatus() {
const pinsStatus = await axios.get('/api/checklist')
return pinsStatus.data === true
},
async clickCheckListHandle() {
if (stepsStatus.value === 'error') return
currentStep.value = currentStep.value + 1
const homeStatus = await this.getHomeStatus()
if(homeStatus) {
currentStep.value = currentStep.value + 1
const pinsStatus = await this.getPinsStatus()
if (pinsStatus) {
currentStep.value = currentStep.value + 1
currentStep.value = currentStep.value + 1
} else {
stepsStatus.value = 'error'
}
} else {
stepsStatus.value = 'error'
}
},
- 引入ant的步骤条,测试状态中使用loading状态,成功使用对号失败红色提示;
- 点击按钮开始测试进行接口调用,并根据返回值来改变步骤条的状态
成果展示
测试不通过展示:
测试通过展示:
这样我们就实现了通过web端点击按钮的自动化测试小例子。