初试 Cypress

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初试 Cypress相关的知识,希望对你有一定的参考价值。

初试 Cypress

Cypress是一款E 20 E的前端测试框架,目前也是我们项目打算使用并且实现自动化的框架。它内部依赖于NodeJS实现,因此可以直接使用 npm install cypress 进行下载,不用继续配置环境感觉还是蛮方便的……

下载后的项目结构如下:

cypress 文件夹下的内容就是最主要的部分,videos的话其实是自动生成的——在命令行运行Cypress会自动生成视频,记录所有的操作。

测试的代码主要在 cypress/integration 下实现,当然,文件夹结构的话就是……一个项目一种风格了吧。

除此之外最重要的就是 cypress.config.js 这个文件了,这个文件取代了 cypress.json 成为了配置文件,当然,老一点的版本还是使用 cypress.json,二者目前看来没有什么特别大的区别,不过同时包含 cypress.jsoncypress.config.js 会引起报错。

目前我的配置文件如下:

const  defineConfig  = require("cypress");

module.exports = defineConfig(
  e2e: 
    setupNodeEvents(on, config) 
      // implement node event listeners here
    ,
    specPattern: 'cypress/integration/examples/*.js',
  ,
  "chromeWebSecurity": false,
  "defaultCommandTimeout": 18000,
  "pageLoadTimeout": 80000
);

specPattern 指定了Cypress会运行所有测试文件——这里就叫Specs,其他的配置就是一些关于跨域和限制时间的了。

运行Cypress

目前在 package.json 中配备了两个指令

  • "run": "cypress run"

    这个指令不打开GUI,直接在命令行中运行所有的测试

  • "open": "cypress open"

    这个指令当然就会打开GUI了,界面如下:

    E2E下的浏览器是需要自己下载的,也就是说你安装了多少Cypress支持的浏览器,Cypress就会显示多少浏览器,默认内置的只有一个Electron。

    作为一个菜鸟,在写PoC的时候我主要还是使用Chrome进行E2E的测试,不过在不需要 console.log() 的前提下也可以考虑使用Electron,感觉直接使用Chrome卡顿还是有些厉害。

    选定了浏览器之后打开的页面如下:

    再点击想要打开的测试文件,就可以进行加载。

简单的案例

下面是我Cypress的测试文件代码:

// cypress - spec
describe('My Cypress study test', function() 
    it('visit local', function() 
        // cy.visit(`$process.cwd()test.html`);
        cy.visit('https://rahulshettyacademy.com/seleniumPractise/#/');
        cy.get('.search-keyword').type('ca');

        cy.get('.product:visible').should('have.length', 4);

        cy.get('.products').find('.product').should('have.length', 4);

        cy.get('.products').as('productLocator');

        // cy.get('.products').find('.product').eq(2).contains('Add To Cart');

        cy.get('.products').find('.product').each(($el, index, $list) => 
            const vegName = $el.find('h4.product-name').text();

            if (vegName.includes('Cashews'))
                // 需要使用 cy.wrap() 包裹 JQ 对象,否则锁不住异步操作
                cy.wrap($el).find('button').click();
        )

        cy.get('.brand').then(logoEl => cy.log(logoEl.text()))
    );

    it('does nothing', function() 
        // do nothing
    )
)

如果有用过其他的测试框架——如React Testing Library,Mocha,Jest等,这个测试风格应该还是挺熟悉的吧,这里也就不再赘述了。

我个人还是挺喜欢Cypress的测试代码的,写起来风格还是挺简单和干练的,并且Cypress内部对异步操作进行了一定程度上的管理。如果所有实现的函数都以 cy 开头,那么这些函数的执行就一定会按序执行。不过Cypress内部也有对JQuery的支持,因此如果要使用JQuery的代码,那么就只能使用callback了,如:

cy.get('.products').find('.product').each(($el, index, $list) => 
    const vegName = $el.find('h4.product-name').text();

    if (vegName.includes('Cashews'))
        cy.wrap($el).find('button').click();
    )

这里的 $el 就是Cypress 内部提供的Jquery对象——直接使用 $ 的话会报 $ is not defined 的错,所以说是Cypress内部提供的Jquery对象。

页面中展现的效果如下:

页面中的回溯也很简单,以找到输入框并输入 ca 两字母为例。首先找到对应输入的操作:

可以看到左边一个紫色的Pin的标记,同时主要的测试页面上也显示了 beforeafter,这时候点击 after 就会获取输入后的结果:

虽然说使用GUI只会影响测试的效率,不过对于新手而言,能够比较切实的回溯并且发现哪里报错,也是一个很方便的事情了。

另外就是,Cypress的selector还是挺强大的,好像也支持XPath搜索,不过这个暂时还没怎么实验过,只是在开会的时候听了一耳朵。

其他

Cypress主要使用的还是assertion,我司目前考虑使用另外一个工具集成兼容Cypress,这样可以抛弃assertion,直接使用UI进行测试,任何UI的变动都会被capture并且进行反馈。

当然,我毕竟还是一个开发,如果之后和我们测试合作有这么紧密,并且我们的测试需要帮助鞋PoC的话,我才会研究一下另一个工具。

以上是关于初试 Cypress的主要内容,如果未能解决你的问题,请参考以下文章

初试 Cypress

在 Cypress 测试中从 @angular/cdk 导入任何内容都会破坏 Angular 13 的构建

Cypress系列- 如何学习 Cypress

Cypress系列- 如何学习 Cypress

初试微信小程序

Cypress系列(16)- 查找页面元素的基本方法