文章分为三部分讲解,项目采用vue-cli + vue/cli-plugin-e2e-cypress配合讲解
vue-cli项目生成 + 基本配置(虽然是傻瓜式?)
- 生成项目(官网爸爸)
npm install -g @vue/cli // 可以用yarn 习惯npm了
vue create hello-world // 创建自己喜欢的工程吧 最近楼主不推荐配置eslint 自己配置eslint + Prettier吧 standard标准不支持Prettier ?
复制代码
- 修改package.json文件
"start": "vue-cli-service serve", // 开发 + 测试环境
"serve": "vue-cli-service serve --mode test", // 联调 + 后端小姐姐
"dev": "vue-cli-service build --mode dev", // 测试环境部署
"build": "vue-cli-service build", // 线上环境部署
复制代码
- 增加配置文件
// 不同环境配置
touch .env.test
echo NODE_ENV = 'development' > .env.test
// webpack alias + webstorm配置(实在不想写../../这种)
touch vue.config.js
const path = require('path')
module.exports = {
configureWebpack: {
plugins: []
},
chainWebpack: config => {
config.resolve.alias
.set('@', path.join(__dirname, 'src'))
.set('component', path.join(__dirname, 'src', 'components'))
.set('config', path.join(__dirname, 'src', 'config'))
// webstorm配置
commond + ,
输出webpack
自定义配置文件 node_modules/@vue-cli/server/webpack.config.js + apply
尽情的command + B ??????
// 不喜欢用lodash get方法 觉得写起来不好看 又不是typescript 幸好有Babel爸爸
npm i '@babel/plugin-proposal-optional-chaining' -D
touch .babelrc
module.exports = {
'presets': [
'@vue/app'
],
'plugins': [
'@babel/plugin-proposal-optional-chaining'
]
}
const a = { c: 1 }
console.log(a?.b) // 不会中断程序执行 是不是写起来很舒服
复制代码
- 让我们写一个vue Loading插件玩玩吧 ?
import Vue from 'vue'
import Loading from './Loading' // Loading 怎么实现 自由发挥
let instance
let ZIndex = 101
const LoadingBuilder = function (type) {
return (options) => {
if (Vue.prototype.$isServer) return false
options = options || {}
let data = Object.assign({}, options, { type: type, ZIndex: ZIndex })
instance = new Loading({
data: data
})
instance.vm = instance.$mount()
document.body.appendChild(instance.vm.$el)
instance.dom = instance.vm.$el
instance.vm.open()
ZIndex = ZIndex + 1
return instance.vm
}
}
const LoadingComponent = {}
LoadingComponent.install = function (Vue, opts = {}) {
const Loading = LoadingBuilder()
Vue.$loading = Loading
window.$loading = Loading
Object.defineProperties(Vue.prototype, {
loading: {
get () {
return Loading
}
},
$loading: {
get () {
return Loading
}
}
})
}
export default LoadingComponent
复制代码
Cypress.io 基本配置
- 安装Cypress在现有项目中
vue add @vue/e2e-cypress
复制代码
-
目录介绍
以下是自动生成的
├── tests
│ └── e2e
│ ├── plugins // 配置测试文件保存的地方
│ │ └── index.js
│ ├── specs // 写测试的地方
│ │ └── test.js
│ └── support // 写自定义命令的地方
│ ├── commands.js
│ └── index.js
复制代码
- 修改package.json文件
"test": "vue-cli-service test:e2e --mode dev", // 本地开发用
"test:e2e": "vue-cli-service test:e2e --headless --mode dev", // 跑Jenkins用的
复制代码
-
基本语法(官网肯定讲的比我清楚,我这个快速入门)
- 断言语法和其他测试框架一样(支持各种断言语法,包括自定义)
expect([]).to.be.a('Array') // 判断类型 expect(a.b).to.exist // 判断属性是否存在 expect(1).to.be.oneOf([1,2,3]) // 判断值是否是其中之一 expect('testing').to.match(/^test/) // 正则匹配 ... 复制代码
- UI测试(感觉和python Selenium挺像)
describe('Test Login', () => { before(() ={}) // 开始钩子 beforEach(() => {}) // 每个测试开始前的钩子 it('login', () => { cy.visit('/') // 访问根目录 cy.visit('http://localhost:3000') cy.url().should('include', '/login') // 断言url 里面包含login cy.get('.user-input') .type('Jack z') .should('have.value', 'Jack z') // 找到input.user-input 并输入Jack z 断言输入的值是Jack z cy.get('.submit-button').click() // 获取.submit-button dom 并触发click事件 cy.get('#navbar').contains('关于').should('have.class', 'is-active') // 获取id为navbar文本内容是关于且有class是is-active cy.wait(1000) // 等待1s cy.pause() // 暂停 cy.server({method: '', header: {token: ''}, ...}) + cy.router('method', 'url', 'config') // 这个网络请求不能debugger cy.request(method, url, config).then(() => {}) // 这个可以debugger cy.contains().find().eq().each() // 跟JQuery一样 找DOM做出UI的判断 ... // 支持动画测试(没用过 明试试 再补充) }) after(() => {}) afterEach(() => {}) } ... 复制代码
- 自定义命令
// 自定义 setLocalStorage Cypress.Commands.add('setLocalStorage', (key, value) => { window.localStorage.setItem(key, value) cy.setLocalStorage('a', JSON.strigify('Jack z')) 复制代码
- 断言语法和其他测试框架一样(支持各种断言语法,包括自定义)
gitlab webhook + jenkins + jenkinsFile基本配置
- Jenkinsfile 配置
// 项目根目录 touch Jenkinsfile
pipeline {
agent {
docker {
image 'cypress/base:10' // 这个镜像包含了cypress运行的环境 推荐(不然你懂得 主要还得运维配合)
args '-u root:root' // 权限配置 不然npm install fail~~~~
}
}
environment {
CHROME_BIN = '/bin/google-chrome' // 全局配置环境变量
}
// Jenkins流水线下的配合
stages {
stage('下载依赖') { // 第一步pipe
steps {
sh 'rm -rf node_modules'
sh 'npm install'
sh 'npm rebuild node-sass'
}
}
stage('运行测试') { 第二步pipe
steps {
sh 'npm run test:e2e'
}
}
}
post {
always {
junit 'results/cypress-report.xml' // CI不通过的错误信息配置文件
// 钉钉通知 完美通知待更新
script {
def msg = "【${author}】你把服务器搞挂了,老詹喊你回家改BUG!"
def imageUrl = "https://www.iconsdb.com/icons/preview/red/x-mark-3-xxl.png"
if (currentBuild.currentResult=="SUCCESS"){
imageUrl= "http://icons.iconarchive.com/icons/paomedia/small-n-flat/1024/sign-check-icon.png"
msg ="【${author}】发布成功,干得不错!"
}
dingTalk accessToken:"xxxx",message:"${msg}",imageUrl:"${imageUrl}",messageUrl:"${BUILD_URL}"
}
}
}
}
复制代码
-
创建docker Jenkins
- jenkins初始化
docker run --name devops-jenkins --user=root -p 8080:8080 -p 50000:50000 -v /opt/data/jenkins_home:/var/jenkins_home -d jenkins/jenkins:lts
docker run --name devops-registry -p 5000:5000 -v /opt/devdata/registry:/var/lib/registry -d registry
启动完jenkins后通过浏览器输入地址http://部署jenkins主机IP:端口
之后主页面上有怎么查看登录的密码
之后选择通用配置
进来之后 开始上图
复制代码
输入完管理员账号后,点击continue as admin 进入管理界面点击系统管理-插件管理中安装node
node版本管理
打包完上传文件
... 插件缺啥按啥
-
建两个任务
1、一个跑测试(这个可以包含第二个 个人喜好)
建任务
2、一个跑部署
建任务
-
gitlab配置
gitlab webhook配置 箭头填写上面?画圈地方
最后,写的不对的地方,欢迎大佬更正