前面讲解了编写UI层自动化测试时cypress提供的常用api,编写脚本过程中不可避免需要进行调试,调试效率直接影响脚本编写成本,下面将介绍4种常用的调试方式。

  1. 添加debugger进行调试
  2. 利用Test Runner进行调试
  3. 开启录屏或者截图功能
  4. 通过测试报告定位失败案例

接下来就开始介绍第一种调试方式。

添加debugger进行调试

编写脚本时可以在cy.get(elementSelector)脚本后面添加debug(),脚本运行到debug()处时会停下来。此时打开浏览器的console界面,可以看到cypress框架对外暴露了subject对象,也就是定位到的页面元素对象,可以在console上面编写语句与subject对象进行交互。通过此方式,可以确定定位页面元素的selector是否正确。

it('let me debug like a fiend', () => {
    cy.visit("https://angular.realworld.io");
    cy.get('app-layout-header ul li a[href="/login"]').debug().click();
    //在test runner上运行此脚本时,会在此处停下来,这样便于确定定位页面元素的selector是否正确

    cy.get('input[formcontrolname="email"]').clear();
    cy.get('input[formcontrolname="email"]').type("e2etest@163.com");
    cy.get('button[type="submit"]').click({force:true});
    cy.get('input[formcontrolname="password"]').clear();
    cy.get('input[formcontrolname="password"]').type("12345678");
    cy.get('button[type="submit"]').click();
})

Test Runner上选择“debugDemo_spec.js”,执行上面的测试脚本,结果如下所示,可以看到脚本在debug()处hold住了.如果检查后确定定位页面元素selector无问题,此时,可以点击调试界面上的“Resume script execution”继续完成后面的脚本。需要注意一点,如果要启动调试模式,需要在Test Runner上打开console界面后,再运行测试脚本。

Cypress只有fixtures和node_modules cypress debug_javascript

前面提到过,Cypress框架很大的一个优势是极大的提升了调试体验,下面介绍如何利用Test Runner进行调试。

利用Test Runner进行调试

利用cypress框架提供的Test Runner可以回放执行过的每一句脚本,如果脚本运行失败,test runner上还会打印详细的错误日志信息,能协助用户很快的定位issue。例如,下面脚本,第二行脚本是错误的脚本。

describe("practice assert element content",() => {
    it("assert it",() => {
        cy.visit("https://angular.realworld.io");
        cy.get('app-layout-header ul li a').eq(1).should('contain','Home');    
        //校验右上角的第二个菜单是“Home”,注意使用eq时,index是从0开始
      })
});

Test Runner上运行该脚本,运行失败,打开浏览器的console界面,点击左边执行记录中“EQ 1”这一行,可以看到cosole中显示了该行脚本的执行细节,可以看到定位到了一个element,说明校验失败不是因为没有查找到element引起的,继续看console中信息,发现定位到的element的text是“Sign in”,看到这里就找到错误根因了。校验失败是因为定位到的element不是“Home”菜单而是“Sign in”菜单。

修改上面的脚本,让最后一行脚本失败,失败元素是定位页面元素的selector错误,脚本内容如下所示。

describe("practice assert element content",() => {
    it("assert it",() => {
        cy.visit("https://angular.realworld.io");
        cy.get('app-layout-header ul li a').eq(0).should('contain','Home');
        cy.get('app-layout-header ul li a').eq(1).should('contain','Sign in');
        cy.get('app-layout-header ul li a').eq(2).should('contain','Sign up');
        cy.get('app-layout-header ul li a[href="/logins"]').click();     
        //修改成错误的定位element的selector,重新运行应该会提示找不到element
})
});

重新运行上面的脚本,可以看到运行失败,还是先点击左边运行记录中的“Get”一行,可以看到console中显示查找到的element个数是0,下面显示了详细的错误信息,从日志看应该是编写的定位element脚本错误了,是不是呢?前面说过cypress底层集成了jQuery,cypress集成jQuery后通过“Cypress..来暴露”jQuery,也就是通过Cypress..来暴露”jQuery,也就是通过Cypress..对外提供jQuery的功能。所以,这里为了验证上面脚本中编写的定位element代码是否正确,可以通过Cypress.('selector')进行验证。验证结果如下所示,先在console中输入命令Cypress.(′selector′)进行验证。验证结果如下所示,先在console中输入命令Cypress.('app-layout-header ul li a[href="/logins"]') ,console中显示查询到的element个数是0,说明使用的定位element的selector确实错误了,再次修改命令为Cypress.$('app-layout-header ul li a[href="/login"]'),可以看到console中显示查询到了一个element,说明修改后的命令正确了,定位到这里说明找到了错误根因并发现了定位element正确的selector。

上面讲解的都是通过test runner运行debug,实际还可以通过命令方式运行测试脚本,通过命令运行时,为了方面调试,可以开启cypress的截图和录屏设置。当运行错误时,可以通过测试报告或者测试截图更快的定位失败原因。

开启录屏或者截图功能

cypress的配置都存放在cypress.package中,配置内容如下所示,通过调整配置信息可获取错误截图。

{
  "defaultCommandTimeOut": 10000,    
   //执行cypress命令时的超时时间,例如执行cy.get(selector),会retry获取期望定位的页面元素,如果操作10秒都没有定位到,脚本就会报错

  "viewportHeight": 1080,      
  "viewportWidth": 1920,
  //设置浏览器的像素

  "video": false,       
  //这里关闭了录屏功能,默认是开启的

 "screenshotOnRunFailure": false,   
 //默认开启截图功能,如果不设置或者设置为true都会截取错误截图;错误截图默认会存放在代码根目录的screenshots目录下

  "testFiles": "**/*_spec.js" 
//指定测试用例文件
}

通过命令运行测试脚本,执行结果如下图所示,命令执行框中提示测试用例失败了,命令中提示未找到某个页面元素,此时打开错误截图可以协助定位错误的位置,缩小排查的范围。

Cypress只有fixtures和node_modules cypress debug_ui_02

上面讲解了通过错误截图定位失败位置,接下来看看如何通过测试报告定位失败案例,这个在CICD上执行大量测试用例时非常有效。实际项目中测试用例会随着时间越来越多,一次性在CICD上全部运行后通过查看测试报告可以快速定位哪些测试用例失败,进而修改失败的测试用例。

通过测试报告定位失败案例

使用cypress时配置测试报告稍微有些复杂,以下是配置生成测试报告步骤。

第一步:执行命令“npm install --save cypress-multi-reporters mocha mochawesome mochawesome-merge mochawesome-report-generator”安装生成测试报告所需的依赖包。执行完后package中应该也会自动配置如下的依赖信息。

dependencies": {
    "cypress-multi-reporters": "^1.2.1",   
    //每个case生成单独的json格式测试报告

    "mocha": "^6.2.2",           
    //前面提到过cypress底层集成了macha这个测试框架,这里生成测试报告也是集成了mocha的一些已有功能,故需要单独引如mocha

    "mochawesome": "^4.1.0",     
    //为了生成后续美化后的html格式测试报告

    "mochawesome-merge": "^2.1.0",   
    //对所有的json格式测试报告进行merge

    "mochawesome-report-generator": "^4.0.1"   
    //将merge后的结果转换为html格式的测试报告
  }

 第二步:代码根目录下创建report.json,该配置文件与package.json在同一目录层,内容如下所示

{
  "reporterEnabled": "mochawesome",
  "mochawesomeReporterOptions": {
    "reportDir": "cypress/reports/mochawesome",    
    //指定生成报告的地址

    "overwrite": false,   
    //重复运行case不进行覆盖,这个可以根据自己实际情况进行设置

    "html": false,    
    //不生成html格式的测试报告

    "json": true   
    //生成json格式测试报告,后面会对每一个测试用例的json格式报告进行合并,合并后再生成统一的html格式报告
  }
}

第三步:cypress.json文件中增加测试报告的配置,内容如下所示

{
  "defaultCommandTimeOut": 9000,
  "viewportHeight": 1080,
  "viewportWidth": 1920,
  "video": false,
  "screenshotOnRunFailure": true,
  "testFiles": "**/*_spec.js",
  "reporter": "cypress-multi-reporters",     
  "reporterOptions": {
    "configFile": "reporter.json"   //制定测试报告配置文件名称
  }
}

第四步:package.json文件中配置两个测试用例,内容如下所示

"scripts": {
    "cypress:open": "./node_modules/.bin/cypress open",
    "debugDemo": "cypress run --spec 'cypress/integration/e2e/course/third/debugDemo_spec.js' ",
    "assertDemo": "cypress run --spec 'cypress/integration/e2e/course/third/assertPractice_spec.js' "
  },

第五步:执行相关命令

  • 执行命令“npm run assertDemo”和“npm run debugDemo”,两个测试用例执行完后,会在cypress/reports/mochawesome中生成两个json格式文件,第一个json文件名字为“mochawesome.json”,第二个json格式文件名字为“mochawesome_001.json”,如果有更多的用例执行,测试报告名称依次类推。
  • 接着执行“npx mochawesome-merge --reportDir cypress/reports/mochawesome > mochawesome.json”,作用是把每个测试用例的测试报告进行合并,生成统一的json格式测试报告,报告名称是“mochawesome.json”,存放在根目录下。
  • 最后执行“npx mochawesome-report-generator mochawesome.json”,执行完后mochawesome-report目录下生成html格式的测试报告。