Cypress(基于JS的UI、API、单元测试自动化测试工具)

小编使用Cypress、PO模式写的UI自动化测试框架Demo可供参考
地址:https://github.com/fengyibo963/DemoUITestCypress

一、Cypress介绍

大多数测试工具(如Selenium)通过在浏览器外部运行并在网络上执行远程命令来运行。Cypress恰恰相反。Cypress在与你的应用程序相同的生命周期里执行。

Cypress背后是Node服务进程。 Cypress和Node进程不断进行通信,同步和执行任务。 访问这两个部分(前端和后端)使我们能够实时响应你的web应用程序的事件,与此同时在浏览器之外也能工作以完成需要更高权限的任务。Cypress还可以通过即时读取和更改网络流量工作在网络(请求)层。 这使得Cypress不仅可以修改进出浏览器的所有内容,还可以更改可能会影响自动化浏览器操作的代码。

因为Cypress是本地安装的, 它可以从系统层提供对自动化任务的服务. 也就是说,比如截图或录屏, 一般的命令执行和请求成为可能.

Cypress提供官网文档、API拓展文档查看使用

二、Cypress安装

2.1 操作系统

Mac OS 10.9+ (Mavericks+), 仅提供64位二进制文件
Linux Ubuntu 12.04+, Fedora 21, Debian 8的64位二进制文件
Windows 7+

2.2 安装NodeJs环境

由于Cypress是基于js语言的工具,操作系统需要安装NodeJs环境。
Mac安装参考、Linux安装参考、Windows安装参考

2.3 安装cypress

cypress需要安装至你的项目文件夹下,因此每个新的项目需要安装一次(或复制旧包)

cd xxx/xxxx/xxx   # 手动创建你的项文件夹并进入该文件夹
npm install cypress --save-dev  # 安装cypress

2.4 启动Cypress

  • 直接启动
    cd xxx/xxxx/xxx   # 进入项目根目录
    ./node_modules/.bin/cypress open  # 启动cypress
    
  • 添加启动脚本
    在根目录添加文件package.json,并写入如下内容
    {
      "scripts": {
        "cypress:open": "cypress open"
      }
    }
    
    cd xxx/xxxx/xxx   # 进入项目根目录
    npm run cypress:open  # 启动cypress
    

三、Cypress使用

3.1 项目文件结构介绍

启动Cypress就会默认创建项目文件结构,并提供demo

|-- cypress
|    -- fixtures    # 外部静态数据
|        -- example.json    # 静态数据文件
|    -- integration    # 测试文件,支持.js .jsx .coffee .cjsx
|        -- xxx.js
|        -- xxx.jsx
|        -- xxx.coffee
|        -- xxx.cjsx
|    -- plugin    # 插件文件
|        -- index.js    # cypress将会在每个spec文件运行之前默认自动包含插件文件 index.js
|    -- support    # 支持文件(可以理解为hooks钩子)
|        -- index.js    #  cypress会默认自动包含支持文件 index.js
|-- cypress.json  # cypress配置文件、环境变量
|-- node_modules  # 安装的cypress包
|-- package.json  # 项目信息,用于CI打包
|-- package-clok.json  # cypress版本信息
  • cypress会自动识别integration文件下的所有js文件为测试用例,可以根据个人需要在此基础上添加文件夹做分类
  • cypress.json默认为空,即cypress设为全部为默认。需要修改配置,就添加配置信息,例如开启截图、录屏、修改各个存储文件夹名称等等,可以参考官网

3.2 测试脚本说明、样例

3.2.1 脚本结构

|-- describe()    # 定义test,会识别该函数为test(可添加备注),可自定义在次分类
|-- context()    # 定义test,会识别该函数为test(可添加备注),等同于describe
|    --it()    # 定义case,识别为每一个it为一个case(可添加备注),每个case单独执行
|    --specify()    # 定义case,识别为每一个it为一个case(可添加备注),每个case单独执行,等同于it

3.2.2 单元测试样例

// 加法函数
function add (a, b) {
  return a + b
}

// 减法函数
function subtract (a, b) {
  return a - b
}

// 除法函数
function divide (a, b) {
  return a / b
}

// 乘法函数
function multiply (a, b) {
  return a * b
}

//定义测试内容
describe('Unit test our math functions', function() {

  //定义测试内容
  context('math', function() {
  
    //定义case
    it('can add numbers', function() {
      expect(add(1, 2)).to.eq(3)  # 检查点,1+2是否等于3
    })

    //定义case
    it('can subtract numbers', function() {
      expect(subtract(5, 12)).to.eq(-7)  // 检查点,5-12是否等于-7
    })
    
    //定义case
    specify('can divide numbers', function() {
      expect(divide(27, 9)).to.eq(3)  // 检查点,27/9是否等于3
    })
    
    //定义case
    specify('can multiply numbers', function() {
      expect(multiply(5, 4)).to.eq(20)  // 检查点,5*4是否等于20
    })
  })
})

3.2.3 UI自动化样例

说明:cypress无法识别新打开浏览器页签的情况,所以对于不同页签需要多个case完成测试

//准备数据
var data = {"search": "惠百施 熊本熊 成人牙刷", "goods": "惠百施 熊本熊 成人牙刷 (颜色随机)","url": "https://www.amazon.cn/dp/B00H4ST192/ref=sr_1_1?__mk_zh_CN=%E4%BA%9A%E9%A9%AC%E9%80%8A%E7%BD%91%E7%AB%99&keywords=%E6%83%A0%E7%99%BE%E6%96%BD+%E7%86%8A%E6%9C%AC%E7%86%8A+%E6%88%90%E4%BA%BA%E7%89%99%E5%88%B7&qid=1590396419&sr=8-1"}

//定义测试
describe('Test', function() {

  //定义case
  it('Search For Goods', function() {
  
    // 访问亚马逊官网
    cy.visit('https://www.amazon.cn') 
    
    // 根据元素class定位搜索框,并输入“惠百施 熊本熊 成人牙刷”
    cy.get('.nav-search-field .nav-input').type(data['search'])
    
    // 检查点,根据元素class定位搜索框,判断是否有值“惠百施 熊本熊 成人牙刷”
    cy.get('.nav-search-field .nav-input').should('have.value', data['search']) 

    // 根据元素class定位搜索按钮,并点击
    cy.get('.nav-search-submit .nav-input').click({force:true})

    // 根据定位搜索框,并点击“惠百施 熊本熊 成人牙刷”
    cy.contains(data['goods']).click({force:true})  
  })
  
  //定义case
  specify('Add Shop Cart', function() {
  
    // 访问商品链接
    cy.visit(data['url'])
    
    // 根据元素selector定位加入购物车按钮,并点击
    cy.get('#add-to-cart-button').click({force:true}) 

    // 等待3000ms
    cy.wait(3000).then(()=>{
    
    // 根据元素selector定位添加购物车成功提示,并比较提示中是否包含“商品已加入购物车”
    cy.get('#huc-v2-order-row-confirm-text > h1').should('contain', '商品已加入购物车')
    
    // 根据元素selector定位价格信息,并比较提示中是否等于“¥85.76”
    cy.get('#hlb-subcart > div.a-row.a-spacing-micro > span > span.a-color-price.hlb-price.a-inline-block.a-text-bold').should('have.text', '¥85.76')
  }) 
  })
})

3.2.4 API测试样例(仅http)

//定义测试
describe('My First Test', function() {

  //定义case
  it('Gets, types and asserts', function() {
  
    // 发送请求,并获取响应
    cy.request({
      method: 'GET',
      url: 'https://www.amazon.cn/',
    }).then((resp)=>{
      // 检查点,验证响应状态是否是200
      expect(resp.status).to.eq(200)
  })
  })
})

3.3 测试执行

Cypress的测试执行可通过应用程序和命令行执行

3.3.1 应用程序进行测试

  • 开始测试,可以选择自带无头浏览器或设备安装的chrome浏览器
    Cypress(基于JS的UI、API、单元测试自动化测试工具)_第1张图片
  • 测试执行,浏览器会直接显示测试过程,如出错可快速定位步骤。也可以通过刷新按钮重新执行测试(令:此时测试文件修改会自动刷新执行)
  • 关闭测试,cypress通过点击stop关闭测试浏览器(即使测试已经结束)
    Cypress(基于JS的UI、API、单元测试自动化测试工具)_第2张图片

3.3.2 命令行执行测试

  • 配置执行命令,package.json文件添加执行命令
    {
        "scripts": {
          "cypress:open": "cypress open",
          "cy:run": "cypress run"  // 添加运行命令
        }
      }
    
  • 命令行执行
    // 指定使用chrome浏览器,运行指定路径测试文件,不设定chrome会默认使用自带无头浏览器
    npm run cy:run -- --browser chrome --spec "cypress/integration/testcases/test_spec.js"
    
    命令参数可以参考官网文档,默认录制执行视频存在于/cypress/videos文件夹中,以及进行屏幕截图存放于/cypress/screenshots文件夹中
  • 结果展示

    Cypress(基于JS的UI、API、单元测试自动化测试工具)_第3张图片

3.4 持续集成Jenkins

集成Jenkins也很简单,只需要创建一个任务添加构建Execute shell即可,写入如下:

#!/bin/bash -ilex  # 说明使用系统环境变量配置
cd xxxxx/xxxx/xxxxxx/xxxxx   # cd到项目根目录
npm run cy:run -- --spec "cypress/integration/testcases/test_spec.js"  # 执行指定测试用例
npm run cy:run -- --spec "cypress/integration/testcases/*.js"  # 执行文件夹下的所有测试用例

四、其他

4.1 UI自动化获取元素定位

Cypress可以使用class、selector、id等方式获取
推荐最简单的获取方式selector(当然稳定的定位方式clss、id会更好)
方法如下图,找到元素后–检查–copy–copy selector
Cypress(基于JS的UI、API、单元测试自动化测试工具)_第4张图片

你可能感兴趣的:(自动化测试)