Skip to content

cypress基础用法

安装启动

可以使用npm进行安装:

sh
npm install cypress --save-dev

修改package.json在scripts中配置启动脚本,--e2e是以端到端的模式启动,--browser chrome是配置执行自动化测试的浏览器:

json
"test:e2e": "cypress open --e2e --browser chrome"

启动cypress根据提示自动创建cypress文件夹,存放测试所用文件;以下是cypress常用目录结构:

--cypress
	--integration 测试文件存放位置
	--e2e e2e测试文件存放位置
	--fixtures 存放json格式的数据
	--support 存放自定义方法、全局配置

推荐新入门生成示例文件,跟着示例文件可以快速入门

会在项目跟目录生成cypress.config.js文件,以下是我的配置:

js
const { defineConfig } = require('cypress')

// 根据环境变量选择合适的配置,自行删除、修改
const env = process.env.NODE_ENV || 'development'
let config

if (env === 'beta') {
  config = {
    visitUrl: 'https://sunqm.com/page/back',
    apiUrl: 'https://sunqm.com/api'
  }
} else {
  config = {
    visitUrl: 'http://localhost:3000/page/back',
    apiUrl: 'http://localhost:3000/api'
  }
}

module.exports = defineConfig({

  component: {
    devServer: {
      framework: 'vue',
      bundler: 'vite'
    }
  },

  e2e: {
    setupNodeEvents (on, config) {
      // implement node event listeners here
    }
  },

  env: config
})

基础使用

下面是两段示例测试代码,包含知识点

1、统一导入使用element-plus

2、引入 Cypress 使代码可以提示

3、beforeEach使每段用例都保持登录状态,避免visit()洗掉

4、根据行里的某一信息获取该行其他信息

首先是element-plus的批量使用,在component.js文件中:

js
// ui库导入
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import { mount } from 'cypress/vue'

Cypress.Commands.add('mount', (component, options = {}) => {
  options.global = options.global || {}
  options.global.plugins = options.global.plugins || []
  options.global.plugins.push({
    install (app) {
      app.use(ElementPlus)
      app.use(ElementPlusIconsVue)
    }
  })

  return mount(component, options)
})

具体测试示例:

js
/// <reference types="Cypress" />

// 获取环境变量的值
const visitUrl = Cypress.env('visitUrl')

describe('权限测试', () => {
  beforeEach(() => {
    cy.visit(visitUrl)

    // 获取并输入测试用户用户名
    cy.get(':nth-child(1) > .el-form-item__content > .el-input > .el-input__wrapper')
      .type('10001')

    // 获取并输入测试用户密码
    cy.get(':nth-child(2) > .el-form-item__content > .el-input > .el-input__wrapper')
      .type('111111')

    // 点击登录按钮
    cy.get('.el-button')
      .click()

    // 确认跳转到了首页
    cy.location('pathname').should('eq', '/page/back/dashboard')

    // 设置本地存储
    cy.window().then((win) => {
      win.localStorage.setItem('token', win.localStorage.getItem('token'))
      win.localStorage.setItem('userInfo', win.localStorage.getItem('userInfo'))
    })
  })

  it('新增用户逻辑', () => {
    cy.visit(`${visitUrl}/manage/user`)

    cy.get('.el-input-group > :nth-child(2)').type('test2')

    cy.contains('搜索').click()

    cy.contains('添加').click()

    cy.wait(1000)

    cy.get('.el-form').within(() => {
      cy.get('.el-form-item .el-input__wrapper input').eq(0).type('test2')
      cy.get('.el-form-item .el-input__wrapper input').eq(1).type('111111')
      cy.contains('确定').click()
    })

    let username
    // 获取特定行的数据,暂存用户名
    cy.get('.el-table__inner-wrapper')
      .contains('tr', 'test2')
      .find('td')
      .eq(1)
      .invoke('text')
      .then(res => {
        username = res
      })

    // 获取特定行的数据,暂存用户名
    cy.get('.el-table__inner-wrapper')
      .contains('tr', 'test2')
      .within(() => {
        cy.contains('修改权限').click()
      })

    cy.get('[data-key="application"] .el-checkbox').eq(0).click()

    cy.get('.el-dialog__footer').contains('确定').click()

    // 登出,换新添加的用户来登录
    cy.get('.dropdown-head.el-tooltip__trigger.el-tooltip__trigger .el-icon')
      .trigger('mouseenter')

    cy.contains('登出').click()

    // 输入新添加的测试用户用户名
    cy.get(':nth-child(1) > .el-form-item__content > .el-input > .el-input__wrapper')
      .then($el => {
        cy.wrap($el).type(username)
      })

    // 新添加的测试用户密码
    cy.get(':nth-child(2) > .el-form-item__content > .el-input > .el-input__wrapper')
      .type('111111')

    // 点击登录按钮
    cy.get('.el-button')
      .click()

    // 确认跳转到了首页
    cy.location('pathname').should('eq', '/page/back/dashboard')

    cy.wait(1000)

    cy.visit(`${visitUrl}/application/app-list`)

    // 可以正常跳转其他页面
    cy.location('pathname').should('eq', '/page/back/application/app-list')

    cy.get('.view').contains('appList').should('exist')
  })

  it('删除用户逻辑', () => {
    cy.visit(`${visitUrl}/manage/user`)

    cy.get('.el-input-group > :nth-child(2)').type('test2')

    cy.contains('搜索').click()

    // 获取特定行的数据,进行删除
    cy.get('.el-table__inner-wrapper')
      .contains('tr', 'test2')
      .within(() => {
        cy.contains('删除').click()
      })

    cy.contains('确定').click()

    // 断言不存在
    cy.get('.el-table__inner-wrapper')
      .contains('tr', 'test2')
      .should('not.exist')
  })
})

总结

真实直观,方便快捷,侵入性低;可持续集成的项目离不开端到端测试,后续要在自己的项目多使用cypress

鄂ICP备19018246号-1