如何进行前端自动化测试
前端自动化测试是确保前端应用程序在各种情况下都能正常工作的关键。以下是进行前端自动化测试的一般步骤:
- 选择适合的测试框架
选择一个适合你项目的前端测试框架是很重要的。一些常见的前端测试框架包括:Jasmine、Mocha、Jest和Cypress等。这些框架都提供了丰富的功能和断言库,可以帮助你编写和运行测试。
- 编写测试用例
根据你的需求,编写测试用例来覆盖你的前端代码。测试用例应该涵盖各种场景和边界条件,以确保应用在各种情况下都能正常工作。例如,可以测试用户界面的交互,验证表单输入的有效性,或者检查特定功能是否按预期工作等。
- 运行测试
使用所选的测试框架来运行你编写的测试用例。测试框架通常提供了命令行接口或者图形界面来运行测试。你可以选择运行所有的测试用例,或者只运行特定的测试套件或测试文件。
- 断言和验证结果
在测试用例中使用断言库来验证测试结果。断言库提供了各种函数和方法,用于比较实际结果与预期结果是否一致。如果断言失败,测试框架会显示详细的错误信息,帮助你快速定位问题。
- 集成到持续集成流程
为了实现持续集成和自动化构建,将前端自动化测试集成到你的持续集成流程中是很重要的。这样可以确保在每次代码提交或者构建时都运行测试,并及时发现潜在的问题。
- 定期维护和更新测试
随着应用的不断开发和演变,测试用例也需要进行维护和更新。当你添加新功能或修复bug时,确保相应的测试用例也得到更新,以反映应用的最新状态。
总结起来,前端自动化测试的关键是选择适合的测试框架,编写全面的测试用例,运行并验证测试结果,并将其集成到持续集成流程中。这样可以保证你的前端应用在不断变化的环境中始终保持稳定和可靠。
更多详细内容,请微信搜索“前端爱好者
“, 戳我 查看 。
使用Puppeteer进行前端自动化测试
Puppeteer 是一个控制 headless Chrome 的 Node.js API 。它是一个 Node.js 库,通过 DevTools 协议提供了一个高级的 API 来控制 headless Chrome。它还可以配置为使用完整的(非 headless)Chrome。
在浏览器中手动完成的大多数事情都可以通过使用 Puppeteer 完成,下面是一些入门的例子:
- 生成屏幕截图和 PDF 页面
- 检索 SPA 并生成预渲染内容(即 “SSR”)
- 从网站上爬取内容
- 自动提交表单,UI 测试,键盘输入等
- 创建一个最新的自动测试环境。使用最新的 JavaScript 和浏览器功能,在最新版本的 Chrome 中直接运行测试
- 捕获网站的时间线跟踪,以帮助诊断性能问题
使用Puppeteer进行前端自动化测试步骤
使用Puppeteer进行前端自动化测试,需要按照以下步骤进行:
- 安装Puppeteer
Puppeteer是基于Node.js的库,因此首先需要在终端中使用npm安装Puppeteer:
npm install puppeteer
- 编写测试脚本
在安装了Puppeteer之后,可以在测试脚本中引入它。以下是一个简单的示例:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.google.com');
await page.type('input[name="q"]', 'puppeteer');
await page.click('input[type="submit"]');
await page.waitForNavigation();
console.log('Title:', await page.title());
await browser.close();
})();
上面的代码打开一个浏览器窗口,导航到Google页面,在搜索框中键入“puppeteer”,并点击提交按钮。然后等待页面导航完成,打印页面标题,并关闭浏览器。
- 运行测试脚本
可以通过以下命令运行测试脚本:
node test.js
这将启动一个新的Chromium浏览器实例,并执行测试脚本。
- 进一步学习和使用
以上是一个简单的Puppeteer测试脚本示例,你可以根据具体情况进行修改和扩展。
另外,Puppeteer提供了丰富的API,可以模拟用户操作、截图、网络拦截等,可以去Puppeteer官网学习更多内容:https://pptr.dev/
使用示例
const puppeteer = require('puppeteer');
const Imap = require('imap'),
inspect = require('util').inspect;
const MailParser = require("mailparser").MailParser
const fs = require('fs');
/*
1、输入符合邮箱规则的邮箱,且不存在在系统中,提示发送邮件成功
2、邮箱为空,点击下一步给出不可为空提示
3、邮箱格式不符合规则,点击下一步相应提示
4、已激活账号,点击下一步相应提示
5、修改邮箱步骤:
输入邮箱账号,在OAO点击该邮箱链接跳转至对应邮箱(只要能打开该邮箱即可);
用户在该邮箱点击对应链接直接进行验证;自动跳转到OAO进入“完成”页面;
// 注意事项
测试需要开通qq邮箱的imap服务,登录qq邮箱,在设置中开通。
需要发送短信验证码,记录授权码,填写在密码的位置
*/
const projectConfiguration = require('./projectConfiguration')
// const pathToExtension = require('path').join(__dirname, 'chrome-win\\chrome.exe');
const pathToExtension = require('path').join(__dirname, '../chrome-mac/Chromium.app/Contents/MacOS/Chromium');
const reportFileName = '学生端修改邮箱';
(async () => {
// 引入projectConfiguration配置文件,必须有
const projectConfiguration = require('./projectConfiguration')
// 删除目录,为了清空前次的垃圾数据,必须有
projectConfiguration.deleteFolderRecursive('./screenshot/' + reportFileName)
projectConfiguration.reportLog('INFO', 'start '+ reportFileName +' Test----------------------------');
const browser = await puppeteer.launch({
executablePath: pathToExtension,
ignoreDefaultArgs: ['--mute-audio', '--disable-extensions'],
defaultViewport: { width: 1366, height: 768 },
headless: false
});
var newEmail = '1037281161@qq.com';
// newEmail = '382445027@qq.com';
var pwd = 'zvqhyemdypdybcbj';
// pwd = 'nwtjimfpxqcabiea';
var host = 'imap.qq.com';
var oriContent = "";
/**
* imap内容
*/
let imap = new Imap({
user: newEmail,
password: pwd,
host: host,
port: 993,
tls: true,
tlsOptions: { rejectUnauthorized: false }
});
function openInbox(cb) {
imap.openBox('INBOX', true, cb);
}
function getAHref(htmlstr){
var reg = /<a.+?href=('|")?([^'"]+)('|")?(?:\s+|>)/gim;
var arr = [];
while(tem=reg.exec(htmlstr)){
arr.push(tem[2]);
}
return arr;
}
imap.once('ready', function () {
openInbox(function (err, box) {
if (err) throw err;
imap.search(['UNSEEN', ['SINCE', new Date().toDateString()], ['FROM', 'notice@bettermorph.com']], (err, results) => {
if (err || !results) {
console.log('you are already up to date');
return;
}
projectConfiguration.reportLog('INFO', `开始获取最新的邮件内容...`);
var result = results[results.length - 1];
var f = imap.fetch(result, { markSeen: true, bodies: '' });
f.on('message', function (msg, seqno) {
console.log('Message #%d', seqno);
var mailparser = new MailParser();
var prefix = '(#' + seqno + ')';
msg.on('body', function (stream, info) {
stream.pipe(mailparser);
mailparser.on("data", function (mail) {
let ar = getAHref(mail.html);
console.log(ar);
if(ar.length == 1){
goVerifyPage(ar[0]);
}
// fs.writeFile('msg-' + seqno + '-body.html', mail.html, function (err) {
// if (err) throw err;
// console.log(seqno + 'saved!');
// });
})
});
msg.once('end', function () {
console.log(seqno + 'Finished');
});
});
f.once('error', function (err) {
console.log(err);
});
f.once('end', function () {
console.log('Connection ended');
imap.end();
projectConfiguration.reportLog('INFO', `邮件已关闭`);
});
});
});
imap.once('error', function (err) {
console.log(err);
});
imap.once('end', function () {
console.log('Connection ended');
});
});
/**
* imap内容
*/
async function goVerifyPage(url) {
projectConfiguration.reportLog('INFO', `打开验证地址:${url}`);
const np = await browser.newPage();
try {
await np.goto(url);
// 进入个人空间
await np.waitFor('button')
await np.waitFor(500);
await np.click('.retrieveSteps button[type="button"]');
// 进入个人空间后,进入个人设置
await np.waitFor('a[href="#/MySet"]')
// 点击个人设置
await np.click('a[href="#/MySet"]');
await np.waitFor('.email_item .MyAccount');
var email = await np.evaluate(() => {
return document.querySelector('.email_item .MyAccount').innerText;
});
console.log(email);
//browser.close();
projectConfiguration.reportLog('INFO', `更改前页面内容:${oriContent} 更改后页面内容:${email}`);
} catch (error) {
}
//browser.close();
projectConfiguration.reportLog('INFO', 'end 修改邮箱 Test----------------------------');
}
// 新建目录,为了保存此次的数据,必须有
projectConfiguration.makeFolderRecursive('./screenshot/' + reportFileName)
const page = await browser.newPage();
await projectConfiguration.initPage(page);
let URL = 'https://www.bettermorph.com/#/studentsLogin';
projectConfiguration.reportLog('INFO', 'ready 测试地址:' + URL);
await page.goto(URL);
await projectConfiguration.login(page, '18713152001', '123456');
await page.waitFor(1000)
let userinfo = await page.$('#userInfo');
if (userinfo) {
// 点击个人主页
await page.click('a[href="#/mySpace"]');
await page.waitFor('a[href="#/MySet"]')
// 点击个人设置
await page.click('a[href="#/MySet"]');
await page.waitFor('.email_item .MyAccount');
var email = await page.evaluate(() => {
return document.querySelector('.email_item .MyAccount').innerText;
});
oriContent = email;
console.log(email);
if (email.indexOf('@') < 0) {
// 代表没有邮箱
projectConfiguration.reportLog('INFO', '需要绑定邮箱 Test----------------------------');
} else {
// 点击修改邮箱
projectConfiguration.reportLog('INFO', '已经绑定邮箱 Test----------------------------');
}
await page.waitFor('a[href="#/StudentRetrieveByMail"]')
await page.click('a[href="#/StudentRetrieveByMail"]');
await page.waitFor('input[type="email"]');
await page.type('input[type="email"]', newEmail, { delay: 10 });
await page.click('.el-button.stepBtn.el-button--default');
// 等待有提示去邮箱认证
await page.waitFor(`a[href="mailto:${newEmail}"]`);
projectConfiguration.reportLog('INFO', `等待10s登录邮箱${newEmail}----------------------------`);
await page.waitFor(10000)
// 登录邮箱,查找notice@bettermorph.com发送的最新邮件
imap.connect();
fs.rename('./testReport.txt', './' + reportFileName + Date.parse(new Date()) + '.txt', (err) => {
if (err) throw err;
console.log('重命名完成');
});
}
})();