Cypress Roll起!高效的前端自动化测试框架!

注:本文章专门针对Cypress实战进行一些前置铺垫

导语

导语:前端自动化测试之路–Cypress

作者:变优秀的小白

注:如中途遇到不懂的地方,直接评论留言看到会马上答疑!

什么是Cypress

一个前端测试工具及框架,基于Mocha和Chai上建立,支持Chai'sBDDTDD断言风格(推荐尽可能使用此风格)

  • Usage
  • E2E 测试、集成测试、单元测试(因为内嵌了 Mocha
  • 任何在浏览器中运行的内容
  • Cypress 提供的一些功能
  • 时间旅行 - 自动等待(类似 Jest 中的 wait
  • 以同步风格的代码完成异步操作
  • 网络流量控制
  • 截屏
  • 持续集成
  • Cypress 语法设计(及内置对象)
  • jQuery + 链式调用
  • PromiseBluebird
  • Mocha + Chai

为什么要用 Cypress

  • 当你需要 E2E 测试
  • 在 2019 年 JavaScript 明星项目 的测试分类中位于第二名
  • 比其他同类 E2E 测试工具更简单、灵活、健壮

项目结构

- /cypress
  - /fixtures(mock 数据)
    - example.json
  - /integration(测试文件)
    - /examples
      - example.spec.js (一般格式为 *.spec.js,可支持.jsx/.coffee/.cjsx)
  - /plugins(用于配置安装的 插件,task 系统)
    - index.js
  - /support(用于调整 自定义选项)
    - commands.js
    - index.js
  - /screenshots(默认截屏文件夹)

Assert Style(断言风格)

Cypress支持BDD(expect/should)和TDD(assert)

ex如下:

# BDD
it('can add numbers', () => {
  expect(add(1, 2)).to.eq(3)
})
# TDD
it('can subtract numbers', () => {
  assert.equal(subtract(5, 12), -7, 'these numbers are equal')
})

Hooks(钩子方法)

Cypress提供hook方法(Mocha)
以下是官方的demo

beforeEach(() => {
  // root-level hook
  // runs before every test
})
describe('Hooks', () => {
  before(() => {
    // runs once before all tests in the block
  })

  beforeEach(() => {
    // runs before each test in the block
  })

  afterEach(() => {
    // runs after each test in the block
  })

  after(() => {
    // runs once after all tests in the block
  })
})

相关配置

被允许的环境配置值(详解!)

每次测试都可以改变的值

  • animationDistanceThreshold
  • baseUrl (用作前缀cy.visit()或cy.request()命令URL的URL)
  • browser
  • defaultCommandTimeout(等待大多数基于DOM的命令超时之前要等待的时间)
  • execTimeout(时间,以毫秒为单位,等待期间,执行系统命令完成)
  • env (任何要设置为环境变量的值)
  • requestTimeout(等待XHR请求在cy.wait()命令中发出的时间,以毫秒为单位)
  • responseTimeout(时间,以毫秒为单位,等待一个响应)
  • viewportHeight
  • viewportWidth
  • waitForAnimations

Suite(测试套件)配置

describe('page display on medium size screen', {
  viewportHeight: 1000,
  viewportWidth: 400
}, () => {
  it('does not display sidebar', () => {
    cy.get('#sidebar').should('not.be.visible')
  })

  it('shows hamburger menu', () => {
    cy.get('#header').find('i.menu').should('be.visible')
  })
})

Test(用例)配置

it('Show warning outside Chrome', {  browser: '!chrome' }, () => {
  cy.get('.browser-warning')
    .should('contain', 'For optimal viewing, use Chrome browser')
})

Dynamic(动态)生成Test(用例)

生成一个suite包含4个event

describe('if your app uses jQuery', () => {
  ['mouseover', 'mouseout', 'mouseenter', 'mouseleave'].forEach((event) => {
    it('triggers event: ' + event, () => {
      // if your app uses jQuery, then we can trigger a jQuery
      // event that causes the event callback to fire
      cy
        .get('#with-jquery').invoke('trigger', event)
        .get('#messages').should('contain', 'the event ' + event + 'was fired')
    })
  })
})

插件

可使用Node代码动态设置,不必再文件中设置环境变量

相关学习地址

githubcypress doc
docker cypress
cypress-example-recipes

总结:大家如果有什么疑问或者建议的地方,可直接留言评论!本人会一一回复!!