最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Cypress首屏加载时间测试

    正文概述 掘金(希沃ENOW大前端)   2021-02-02   551

    本文作者 Cypress首屏加载时间测试

    Cypress是常见的UI测试框架之一,UI测试的场景不做赘述,本文旨在探索Cypress检测页面首屏加载时间的最佳实践,目的是为了检测页面首屏加载的性能。文章主要包含实现逻辑、数据保存和报告生成三部分。

    API介绍

    本文主要使用到了Cypress提供的hooks,包含before、after、beforeEach和afterEach,可理解为测试用例不同的生命周期,具体说明如下:

    describe('Hooks', () => {
      before(() => {
        // runs once before all tests in the block
        // 在所有用例之前触发一次
      })
    
      after(() => {
        // runs once after all tests in the block
        // 在所有用例之后触发一次
      })
    
      beforeEach(() => {
        // runs before each test in the block
        // 在每个用例之前触发一次
      })
    
      afterEach(() => {
        // runs after each test in the block
        // 在每个用例之后触发一次
      })
    })
    

    实现逻辑

    说到页面首屏加载时间,我们不难想到可以通过获取页面加载前后时间戳之差来计算,根据刚刚介绍的hooks函数,我们可利用before和after钩子实现简单逻辑,代码如下

    let startTime;
    const url = '';
    describe('test fp', () => {
      before(() => {
        startTime = +new Date();
      })
    
      after(() => {
        const fp = +new Date() - startTime;
      })
      
      it(() => {
      	cy.visit(`${url}`);
      })
    })
    

    这段代码存在两个比较明显的问题

    1. 没有描述页面完成加载的标志,代码层面表现为cy.visit()没有给出断言,这样会导致计算出的首屏加载时间不准确。
    2. 只对页面的首屏加载时间进行一次计算,结果可能存在误差,需要完善为多次测试取均值。

    针对以上两个问题,我们把用例进行调整,利用dom结构进行断言确认页面已完成加载;并增加一个for循环测试该用例,利用beforeEach和afterEach钩子完成首屏加载时间计算。代码如下,最终5次测试结果保存在fpArr数组中

    const TEST_TIMES = 5;
    let startTime;
    let fpArr = [];
    const url = '';
    describe('test fp', () => {
      beforeEach(() => {
        startTime = +new Date();
      })
    
      afterEach(() => {
        fpArr.push(+new Date() - startTime);
      })
     
      for (let i = 0; i < TEST_TIMES; i++) {
        it((`加载页面`) => {
      	  cy.visit(`${url}`)
            .get('.app-container', { timeout: 10000 })
            .should('have.length', 1);
        });
      }
    })
    

    数据保存

    为了完善用例,可将历史数据进行保存记录,便于后续数据提取对比。实现思路如下

    定义cy.collectData命令,将数据序列化后以参数的形式传入,执行node collectData.js,完成数据写入,如下

    Cypress.Commands.add('collectData', data => {
      // 将参数序列化
      const argv = ...
      cy.exec(`node collectData.js ${argv}`);
    });
    

    collectData.js主要是利用fs提供的文件读写能力完成数据写入,如下 。

    // 将参数反序列化
    const argv = ...
    // 读取已有数据并合并数据
    const filePath = path.join(process.cwd(), path.join('cypress/data', argv.dir));
    const fileJSON = JSON.parse(fs.readFileSync(filePath).toString() || '[]');
    fileJSON.push(argv);
    // 写入
    fs.writeFileSync(filePath, JSON.stringify(fileJSON, null, '  '));
    

    接着便可通过cy.collectData收集首屏加载时间,具体用法如下。

    cy.collectData({
      dir: 'fp.json',
      startTime,
      fp,
    });
    

    报告生成

    对于测试用例而言,报告的可读性和可用性及其重要,好的测试报告可以帮开发者快速获取结果、定位问题。

    在本文的场景中,首屏性能不能仅以是或否通过这种简单标准来衡量,还需要在报告中提供一份首屏加载时间数据便于查看分析,因此需要将测试数据层现在报告中。

    使用mochawesome模块可以生成漂亮的HTML、JSON等格式的报告,mochawesome提供的addContext API可以将附加信息记录在mochawesome的报告中,使用方法如下

    const addContext = require('mochawesome/addContext');
    cy.once('test:after:run', test => {
      addContext({ test }, {
        title: '首屏时长',
        value: 234,
      });
    });
    

    可以将该方法封装为一个Cypress Command(如下),通过cy.addContext使用。

    const addContext = require('mochawesome/addContext');
    
    Cypress.Commands.add('addContext', (context) => {
      cy.once('test:after:run', test => {
        addContext({ test }, context);
      });
    });
    

    使用addContext记录的数据,最终会层现在生成的报告(以JSON报告为例)中。 如下,context字段记录着我们通过addContext增加的信息。

    [mochawesome_0001.json] Cypress首屏加载时间测试

    然而addContext有一个局限性,即mochawesome没有将该字段数据层现在可视化报告中,因此可读性较差。笔者摸索了一种方式在可视化报告中打印这部分信息。

    基于mochawesome模块的源码,在mochawesome/src/mochawesome.js中,增加consoleContext逻辑。以4.1.0版本为例,在runner的end事件回调中增加consoleContext(suites),如下

    function Mochawesome(runner, options) {
      ...
      runner.on('end', () => {
        try {
          const suites = this.runner.suite.suites;
          consoleContext(suites);
          ...
        } catch (e) {
          // required because thrown errors are not handled directly in the
          // event emitter pattern and mocha does not have an "on error"
          /* istanbul ignore next */
          log(`Problem with mochawesome: ${e.stack}`, 'error');
        }
      });
    }
    

    consoleContext的思路是提取每个用例结果中的context,并将其组合在一个对象中,利用console.table打印出来。代码如下,

    function consoleContext(suites) {
      var family = {};
      for (let i = 0; i < suites.length; i++) {
        const tests = suites[i].tests;
        for (let j = 0; j < tests.length; j++) {
          const t = tests[j];
          if (!t.context) {
            continue;
          }
          Object.keys(t.context.fields).forEach(key => {
            const value = t.context.fields[key];
            !family[t.title] && (family[t.title] = {});
            family[t.title][key] = value;
          });
        }
      }
      console.table(family);
    }
    

    最终使用方法为

    cy.addContext({
      title: '首屏时长',
      value: '首屏时长',
      fields: {
        '页面url': 'http://baidu.com',
        '版本': '0.0.1',
        '第一次加载/ms': 2000,
      }
    });
    

    如下图的表格,成功将context数据可视化。 Cypress首屏加载时间测试 当然,你也可以参考mochawesome自定义一个reporter来完成报告输出。

    小结

    回到一开始的首屏时间测试用例,结合以上介绍的逻辑实现、数据保存和报告生成,最终我们可以写出一个完整的用例

    const TEST_TIMES = 5;
    let startTime;
    let fpArr = [];
    const url = '';
    describe('test fp', () => {
      beforeEach(() => {
        startTime = +new Date();
      })
    
      afterEach(() => {
        const fp = +new Date() - startTime;
        fpArr.push(fp);
        // 记录数据写入本地文件
        cy.collectData({
          dir: 'fp.json',
          pageUrl: url,
          fp,
          version: '0.0.1',
        });
        
        // 打印context信息
        let fields = {};
        fpArr.forEach((item, index) => {
          fields[`第${index+1}次/ms`] = item;
        });
        cy.addContext({
          fields,
          title: '首屏时长',
          value: '首屏时长'
        });
      })
     
      for (let i = 0; i < TEST_TIMES; i++) {
        it((`加载页面`) => {
      	  cy.visit(`${url}`)
            .get('.app-container', { timeout: 10000 })
            .should('have.length', 1);
        });
      }
    })
    

    生成报告如下 Cypress首屏加载时间测试


    起源地下载网 » Cypress首屏加载时间测试

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元