Web 自动化测试实践

1,209 阅读4分钟

背景

项目开发完,自测非常重要,改完一个功能,每次都手动去模拟用户去操作一遍,特别对于一些重复性较高的功能或组件,这样效率比较低而且耗时间,如果给我们项目编写自动化测试,能极大的提高我们的开发自测效率,减少重复工作,节省人力和时间。

结论: 自动化的收益 = 迭代次数 x 全手动执行成本 - 首次自动化成本 - 维护次数 x 维护成本

UI自动化测试选型

从目前的项目来说,单元测试维护成本比较高,服务接口测试服务器那边有做,我们项目大部分是GUI,比较适合跑UI自动化测试,从以下对比项来选择适合项目开发的自动化测试框架:

  • Github关注度
  • 技术支持
  • 是否经常维护
  • 社区是否活跃
  • 是否易上手
对比项PuppeteerNightwatchNightmarePhantomJSCaseperJSTestCafeCypress
社区,关注度Google开发,前景好,社区贡献活跃vue-cli推荐,有维护没有维护,拥抱Puppeteer没有维护,拥抱Puppeteer新版会从PhantomJS迁移到Puppeteer开源时间短,社区和生态不够成熟vue-cli推荐,有维护
完善性其他测试需引入第三方库,比如像断言,编排,结果上报等完整的端到端测试框架,还可以编写Node.js单元和集成测试类似PhantomJS完整端对端测试框架,特殊链接不能快照在PhantomJS易用性API上的一些封装,特殊链接不能快照不支持录屏和dom快照完整的测试框架
易用性易用简单,性能高,可以无界面执行npm安装麻烦,vue-cli已经配置好,使用较简单非常简单的测试语法安装麻烦了点比Phantom好用点执行慢但报告简洁用例执行时间长,vue-cli安装比较慢,代码简洁
Star52k9.5k17.5k26.9k7.3k7.2k13.5k

以上是当前比较流行的测试框架,从里面选出了三个比较好的测试框架,分别为 Puppeteer、Nightwatch、Cypress,最后可以根据项目情况来使用。

Puppeteer

npm i puppeteer
  • (3)编写测试用例:
// app.js
// 场景 -> 模拟用户打开不同语言的校讯通帮助说明页面,并点击对该问题是否有帮助,最后生成相关语言截图

const puppeteer = require('puppeteer');
const chalk = require('chalk');

// 异步执行代码
(async () => {

    // 创建一个浏览器实例对象,headless为true表示不打开浏览器
    const browser = await puppeteer.launch({
        headless: true
    });

    try {
        // 通过实例创建页面 page对象
        const page = await browser.newPage();

        // 监听日志并打印到控制台
        page.on('console', msg => {
            for (let i = 0; i < msg.args().length; ++i)
                console.log(`${i}: ${msg.args()[i]}`);
        });

        // 设置为iphone6大小的视区
        await page.setViewport({
            height: 667,
            width: 375
        });
        let projectUrl = `项目地址?language=`;
        let urlList = [`${projectUrl}zh-CN`, `${projectUrl}en`, `${projectUrl}th`, `${projectUrl}in-ID`, `${projectUrl}zh-HK`]

        for (let i = 0; i < urlList.length; i++) {
        console.log(urlList[i])
        // 打开指定的页面
        await page.goto(urlList[i]);

        // 延迟操作,打开页面加载需要时间
        await page.waitFor(500);

        // 打印页面标题
        console.log(chalk.green(await page.title()));

        // 点击反馈
        await page.click('#like');

        // 截屏并保存
        await page.screenshot({
            path: 'pic' + i + '.png'
        });
        }

        // 执行完成关闭浏览器
        await browser.close();

    } catch (e) {
        console.log(chalk.red('error'));
    }
})();
  • (4)测试命令:

node app.js

  • (5)效果图:

Nightwatch

  • (1)官方文档
  • (2)安装: 通过vue-cli3脚手架安装,选择E2E测试框架 > 勾选Nightwatch。 或者通过npm安装nightwatch,建议用vue-cli安装,可以省去很多配置。

  • (3)编写测试用例:
// tests/e2e/specs/test.js
// 场景 -> 模拟用户输入答案,判断输入是否符合预期并截图

module.exports = {
  "default e2e tests": browser => {
    browser
      .url(process.env.VUE_DEV_SERVER_URL) // 打开当前功能页面
      .waitForElementVisible("#app", 5000) // 指定元素指定时间内是否可见
      .assert.elementPresent(".hello") // 检查 DOM中是否存在给定元素
      .assert.containsText("h1", "Please enter your answer") // 检查给定元素是否包含指定的文本
      .setValue(".search", "2", function() {
        browser.click(".submit", function() {
          browser.saveScreenshot("reports/result.png"); // 模拟用户在文本框输入2,点击提交并截图
        });
      })
      .end(); // 关闭页面
  }
};
  • (4)测试命令:

npm run test:e2e

  • (5)效果图:

Cypress

  • (1)官方文档

  • (2)安装: 通过vue-cli3脚手架安装,选择E2E测试框架 > 勾选Cypress。 或者通过npm安装Cypress,建议用vue-cli安装,可以省去很多配置。

  • (3)编写测试用例:

// tests/e2e/specs/test.js
//  场景 -> 模拟用户输入答案,判断输入是否符合预期并截图

describe("My First Test", () => {
  it("Visits the app root url", () => {
    cy.visit("/"); // 打开当前功能页面
    cy.contains("h1", "Please enter your answer"); // 检查给定元素是否包含指定的文本
    cy.get(".search"); // 获取搜索输入框
      .type("2"); // 模拟用户输入2
    cy.get(".submit").click(); // 点击提交搜索结果
    cy.screenshot('example'); // 截图
  });
});
  • (4)测试命令:

npm run test:e2e

  • (5)效果图:

总结

puppeteer

  • 怕安装麻烦,怕执行慢,直接使用 Puppeteer
  • 喜欢无界面测试的可以用 puppeteer
  • 传统页面开发可以用 Puppeteer

nightwatch

  • vue-cli 新建的项目可以用 Nightwatch
  • 要做断言、请求 mock、结果上报等所需功能,又不想配置其它的依赖项的话可以用Nightwatch

Cypress

  • vue-cli 新建的项目可以用 Cypress
  • 喜欢有界面,而且可以看测试状态菜单,操作回放等可以用Cypress
  • 要做断言、请求 mock、结果上报等所需功能,又不想配置其它的依赖项的话可以用Cypress
  • 喜欢简洁的语法