五.前端测试
前言
前端测试需要用到工具,以及测试相关工具用法,测试相关场景
监听测试用例运行,每次修改文件会自动重新跑测试用例,不用每次手动跑
js
yarn run test:unit --watch
1.unit
测试 props 传值
- Test1.vue
vue
<template>
<h1>{{ msg }}</h1>
</template>
js
{
props: {
msg: String
}
}
test1.spec.js
js
const msg = "new message"
const wrapper = shallowMount(Test1, {
propsData: { msg },
})
expect(wrapper.text()).to.include(msg)
测试点击事件
Test2.vue
vue
<template>
<span id="count">{{ count }}</span>
<button @click="increment">点击</button>
<template></template>
</template>
js
{
data() {
return { count: 10};
},
methods: {
increment() {
this.count++;
}
}
}
test2.spec.js
js
let wrapper = shallowMount(Test2)
wrapper.setData({ count: 10 })
expect(wrapper.find("span").text()).to.be.equal("10")
wrapper.find("button").trigger("click")
expect(wrapper.find("span").text()).to.be.equal("11")
测试自定义方法
Test3.vue
vue
<template>
<Child @show="show"></Child>
<p id="content" v-if="flag">{{ name }}</p>
</template>
js
props:{
fn:{}
},
methods:{
clickMe(){
this.fn('123')
this.fn('456')
}
}
test3.spec.js
js
let wrapper = shallowMount(Test3)
expect(wrapper.find("#content").exists()).to.be.false
wrapper.find(Child).vm.$emit("show")
expect(wrapper.find("#content").exists()).to.be.true
测试子组件触发父组件方法
Child.vue
vue
<template>
<button @click="clickMe">click</button>
</tempalte>
js
import Child from "./Child.vue";
export default {
data() {
return {name: "javascript", flag: false };
},
methods: {
show() {
this.flag = true;
}
},
components: {
Child
}
};
</script>
child.spec.js
js
let callback = sinon.spy()
let wrapper = shallowMount(Child, {
propsData: { fn: callback },
})
wrapper.find("button").trigger("click")
expect(callback.getCall(0).args[0]).to.be.equal("123")
expect(callback.getCall(1).args[0]).to.be.equal("456")
expect(callback.callCount).to.be.equal(2)
测试 axios
Test4.vue
vue
<template>
<span >{{user}}</span>
</tempalte>
js
{
data(){
return {user:''}
},
mounted(){
axios.get('/user').then((res)=>{
this.user = res.data.user;
}).catch(err=>{
console.log(err);
});
}
}
test4.spec.js
js
beforeEach(() => {
moxios.install()
})
afterEach(() => {
moxios.uninstall()
})
it("测试axios", (done) => {
let wrapper = shallowMount(Test4)
moxios.stubRequest("/user", {
status: 200,
response: { user: "jw" },
})
moxios.wait(() => {
expect(wrapper.text()).to.include("jw")
done()
})
})
测试 vuex
Store.vue
vue
<template>
<div>
<span>{{ this.$store.state.username }}</span>
<button @click="clickMe">点击</button>
</div>
</template>
<script>
// 测试vuex 从两个方向 测试ui 测试功能
import { mapState, mapActions } from "vuex"
export default {
computed: {
...mapState(["username"]),
},
methods: {
...mapActions(["set_username"]),
clickMe() {
this["set_username"]("jw")
},
},
}
</script>
store.js
js
export default {
state: {
username: "zfpx",
},
mutations: {
set_username(state, username) {
state.username = username
},
},
actions: {
set_username({ commit }, username) {
commit("set_username", username)
},
},
}
main.js
js
import Vue from "vue"
import App from "./App.vue"
import router from "./router"
import config from "./store"
import Vuex from "vuex"
Vue.use(Vuex)
let store = new Vuex.Store(config)
Vue.config.productionTip = false
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app")
store.spec.js
js
import { shallowMount, createLocalVue } from "@vue/test-utils"
import Vuex from "vuex"
import Store from "@/components/Store.vue"
let localVue = createLocalVue()
localVue.use(Vuex) //防止用例之间的污染
let state
let store
let actions
let callback = jest.fn()
describe("测试vuex 能否在页面中使用", () => {
state = { username: "jw" }
actions = {
set_username: callback,
}
beforeEach(() => {
state = { username: "jw" }
store = new Vuex.Store({
state,
actions,
})
})
it("state能否正常显示到页面中", () => {
let wrapper = shallowMount(Store, {
localVue,
store,
})
expect(wrapper.text()).toContain("jw")
})
it("点击按钮时action能否正常触发", () => {
let wrapper = shallowMount(Store, {
localVue, //提供测试的构造函数vue
store,
})
wrapper.find("button").trigger("click")
expect(callback).toHaveBeenCalled()
})
})
将 store 中的部分内容放到 main.js 中可以改造得更简洁
js
import { createLocalVue } from "@vue/test-utils"
import Vuex from "vuex"
import config from "@/store"
let localVue = createLocalVue()
localVue.use(Vuex) //防止用例之间的污染
describe("测试vuex 能否在页面中使用", () => {
let store
beforeEach(() => {
store = new Vuex.Store(config)
})
it("state能否正常显示到页面中", () => {
expect(store.state.username).toBe("zfpx")
jest.useFakeTimers() //创建一个模拟的定时器,会把异步代码立刻返回
store.dispatch("set_username", "newName")
jest.runAllTimers() //把timer执行
expect(store.state.username).toBe("newName")
jest.useRealTimers()
})
})