前端自动化测试学习

前端自动化测试BDD与集成测试学习记录

2020-06-23  本文已影响0人  Mstian

BDD(Behavior Driven Development)行为驱动开发

集成测试: 完全是用测试脚本去模拟用户操作,比如打开浏览器,点击登录,输入用户名,密码等。然后判断是否达到预期的结果来进行测试。
概念解释:

story:一个场景,可以理解成一个步骤,用户某一阶段操作的集合。

比如在例子TodoList中,用户在header输入框中输入内容,敲击enter键,对应下面任务列表新增一个任务。这就是一个story。

先看一个BDD的例子:

import { mount } from '@vue/test-utils'
import TodoList from '../../TodoList.vue'
import { createWrapper } from '../../../../utils/utilTest'

it(`
    1. 输入内容
    2. 触发事件
    3. 列表项增加
`,async () => {
    const wrapper = mount(TodoList)
    let inputEle = createWrapper(wrapper, 'test-input').at(0)
    const content = "hello"
    inputEle.setValue(content)
    await inputEle.trigger('change')
    await inputEle.trigger("keyup.enter")
    const listItem = createWrapper(wrapper,'test-item')
    expect(listItem.length).toBe(1)
    expect(listItem.at(0).text()).toContain(content)
})

首先模拟用户行为,分为三个步骤,第一步输入内容,第二步触发事件,第三步对应列表项增加,依次步骤为指导然后写测试用例,在写的过程中,由于模拟用户行为时,进行了跨组件测试,因此使用集成测试的方案,使用mount进行深度渲染。注意在写有触发事件的测试用例中,使用async/await异步处理方式,否则时间执行结果无法获取到。

通过例子分析TDD与BDD两种模式

TDD:

BDD:

Vuex项目测试例子

import { mount } from '@vue/test-utils'
import TodoList from '../../TodoList.vue'
import { createWrapper } from '../../../../utils/utilTest'
import store from '../../../../store'
it(`
    1. 输入内容
    2. 触发事件
    3. 列表项增加
`, async () => {
  const wrapper = mount(TodoList, {
    store
  })
  var inputEle = createWrapper(wrapper, 'test-input').at(0)
  const content = 'hello'
  inputEle.setValue(content)
  await inputEle.trigger('change')
  await inputEle.trigger('keyup.enter')
  const listItem = createWrapper(wrapper, 'test-item')
  expect(listItem.length).toBe(1)
  expect(listItem.at(0).text()).toContain(content)
})

在项目中使用了Vuex时,在测试时需要将store引入到测试组件中,否则测试组件中是没有Vuex的。具体就是在渲染组件的时候进行传参。

const wrapper = mount(TodoList, {
  store
})

两种测试模式混合使用

比如上面代码是对项目功能进行的集成测试

同时也可以在项目中再使用单元测试

比如对Vuex中的逻辑进行单元测试

import store from '../../../../store'
it("测试提交commit inputValue跟着变化", () => {
  const content = '123'
  store.commit("changeInputValue",content)
  expect(store.state.inputValue).toBe(content)
})

两种测试模式如何选取?

测试业务的时候一般选择BDD+集成测试

测试函数库的时候优先选择TDD+单元测试

一般情况下可以采用两种模式结合使用对项目进行测试。

异步测试

比如在组件中需要使用axios获取数据并显示到页面中,此时的测试策略如下:

首先前端测试不去测试请求返回值的格式以及数据正确与否,这一步应该是由后端支持。否则通过调取后端数据既耗时又耗资源,对于前端测试来说比较慢,等等。

然后异步测试主要是前端根据与后端协商好的数据格式等,自行模拟一个前端数据,然后进行测试。

在containers/TodoList文件夹下创建__mocks__文件夹然后创建一个axios.js文件

const list = {
    success: true,
    data: [
        {
            type: 'div',
            value: 'hello'
        },
        {
            type: 'div',
            value: 'sasasa'
        }
    ]
}

export default {
    get(url) {
        if (url == "/getList.json") {
            return new Promise((resolved, rejected) => {
                setTimeout(() => {
                    resolved(list)
                }, 3000)
            })
        }
    }
}

__tests__/integration/TodoList.js

import { mount } from '@vue/test-utils'
import TodoList from '../../TodoList.vue'
import { createWrapper } from '../../../../utils/utilTest'
import store from '../../../../store'
beforeEach(()=>{
  jest.useFakeTimers()
})
it(`
    1. 首次进入从远程获取数据
    2. 将数据展示到列表中
`, () => {
  const wrapper = mount(TodoList, {
    store
  })
  jest.runAllTimers()
  wrapper.vm.$nextTick().then(() => {
    const listItems = createWrapper(wrapper, 'test-item')
    expect(listItems.length).toBe(2)
  })
})

需要注意的是:使用setTimeout的时候需要使用jest.useFakeTimers()去做处理,然后在使用异步获取数据的时候,需要使用Vue实例的nextTick()方法中再去做断言。

模拟异步失败测试:比如axios获取数据失败,组件应该显示0条数据

设置一个变量控制axios的resolved和rejected执行

export default {
    get(url) {
        if (url == "/getList.json") {
            return new Promise((resolved, rejected) => {
                if(this.success){
                    resolved(list)
                }else{
                    rejected(new Error())
                }
            })
        }
    }
}

在测试用例中:

import axios from '../../__mocks__/axios.js'
beforeEach(()=>{
  axios.success = true
})
it(`
    1. 首次进入从远程获取数据失败时应该展示0条
    2. 将数据展示到列表中
`, (done) => {
  axios.success = false
  const wrapper = mount(TodoList, {
    store
  })
  wrapper.vm.$nextTick().then(() => {
    const listItems = createWrapper(wrapper, 'test-item')
    expect(listItems.length).toBe(0)
    done()
  })
})

注意,由于$nextTick为异步执行,所以需要配合done方法使用,否则测试代码只会走到nextTick上面便认为测试通过。

源代码地址:https://github.com/Mstian/inte-test

上一篇下一篇

猜你喜欢

热点阅读