cypress自动化测试
官方文档 https://docs.cypress.io/api/commands/and
常用方法:
cy.get(‘div’) 定位元素位置,定位的是页面所有的元素
cy.find(‘div’) 定位元素位置,定位的是当前dom下的元素
cy.request() 发送http请求
cy.intercept(‘get’, ‘**/hello/*’).as(‘hello’) 设置接口或者页面的别名,组合 cy.wait(‘@hello’) 可以等待接口完成后,执行下一步
cy.get(‘div’).click({force:true}) 点击,force 强制执行
cy.get(‘div’).rightclick() 右键点击
cy.visit(‘http://www.baidu.com’) e2e测试时的访问方法,组件测试时应该用不上
cy.contains(‘开始’) 用于定位文字
e2e自动化测试
测试流程:登录->执行操作->完成任务
- 登录
在 文件里 cypress\support\commands.ts 定义全局命令
登录可以直接调用后端接口,处理数据,减少页面的流程
Cypress.Commands.add('login_request', () => {
Cypress.on('uncaught:exception', (err, runnable) => {
//监听被测应用未捕获的异常信息
return false
//如果发现异常信息,不阻断测试脚本运行,默认情况下会阻断测试脚本运行,并显示错误信息
});
cy.request({
method: 'post',
url: 'http://localhost:3000/api/auth/oauth/token',
body: {
grant_type: 'password',
password: '123456',
username: 'xxx@qq.com'
},
headers: {
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
"user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
"X-Requested-With": "XMLHttpRequest",
'authorization': 'Basic bHZhbndlYjpMdmFuaXRlY2hAMjAyMQ=='
}
})
.its('body')
.as('res')
.then(function () {
//存入localStorage
window.localStorage.setItem('userId', JSON.stringify(this.res.tenantUserInfo && this.res.tenantUserInfo.userId))
})
// cy.intercept('post', 'http://localhost:3000/lvanitech/api/auth/oauth/token').as('token')
// cy.wait('@token')
// 等待user-info接口执行完
cy.visit('http://localhost:3000/home')
cy.wait('@userInfo')
})
- 执行任务
// it 定义每个测试用例
// beforeEach 执行测试用例之前会执行
describe('流程测试', () => {
beforeEach( function () {
cy.intercept('GET', '**/home/*').as('toHome')
cy.intercept('GET', '**/user-info').as('userInfo')
cy.login_request() //command.js中定义的登录命令
})
const now = Date.now()
it('测试', () => {
cy.to_control()
cy.get('.site-content-main .draft').click({ force: true })
cy.get('.draft-paper input[data-index=filename]').type(now)
cy.get('.draft-paper form').children().eq(2).find('input').click({ force: true })
cy.get('.el-popper[aria-hidden=false] .el-select-dropdown ul>li').eq(0).click({ force: true })
cy.get('.draft-paper form').children().eq(3).find('input').click({ force: true })
cy.get('.el-popper[aria-hidden=false] .el-select-dropdown ul>li').eq(0).click({ force: true })
cy.get('.draft-paper form').children().eq(5).find('input').click({ force: true })
cy.get('.el-popper[aria-hidden=false] .el-select-dropdown ul>li').eq(0).click({ force: true })
cy.get('.draft-paper form').children().eq(6).find('input').type(now)
cy.get('.draft-paper form').children().eq(8).find('input').click({ force: true })
// cy.get('.draft-paper form').children().eq(9).find('input').type('2022-12-01', { force: true })
cy.get('.el-popper[aria-hidden=false] .arrow-right').click({ force: true })
cy.get('.el-popper[aria-hidden=false] tr').contains('10').click({ force: true })
cy.get('.el-popper[aria-hidden=false]').contains('确定').click({ force: true })
cy.get('.draft-paper').contains('确定').click({ force: true })
})
})
- 完成任务
组件测试
自定义组件
在文件 cypress\support\component.ts 里面定义 mount 方法
将main.js 中引入的css 或者组件等,在这里引入,然后挂载可以使得element或者其他生效。
import { createApp } from 'vue'
import i18n from '../../src/lang/index'
import router from '../../src/router/index'
import ElementPlus from 'element-plus'
import plugin from '../../src/plugins/index'
import uploader from '../../src/uploader/index'
// ***********************************************************
// This example support/component.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
import { mount } from 'cypress/vue'
import 'virtual:windi.css'
import ElementPlus from 'element-plus'
import 'element-plus/theme-chalk/index.css'
import '../../src/assets/css/index.scss'
import '../../src/assets/css/media.scss'
import 'dayjs/locale/zh-cn'
// Augment the Cypress namespace to include type definitions for
// your custom command.
// Alternatively, can be defined in cypress/support/component.d.ts
// with a <reference path="./component" /> at the top of your spec.
declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount
}
}
}
// Cypress.Commands.add('mount', mount)
Cypress.Commands.add('mount', (component, options = {}) => {
// const app = createApp(component)
// app.use(i18n).use(router).use(ElementPlus).use(plugin).use(uploader)
// mount(app)
options.global = options.global || {}
options.global.plugins = options.global.plugins || []
// options.router = router
// Add router plugin
options.global.plugins.push({
install(app) {
// app.use(options.router)
app.use(ElementPlus)
},
})
return mount(component, options)
})
// Example use:
// cy.mount(MyComponent)