TDD vs BDD
在开始之前,我们需要先了解两种编写测试用例的方式,以便在实际开发中选取合适的方式。
Test Driven Development (TDD) 测试驱动开发
TDD 的原理就是在编写代码之前先编写测试用例,由测试来决定我们的代码,而且 TDD 更多的需要编写独立的测试用例,比如只测试一个组件的某个功能点,某个工具函数等。它是白盒测试。
开发流程大致是:编写测试用例、运行测试、编写代码使测试通过、优化代码。
TDD 的优势:从长期来看,可以有效减少回归测试的 Bug;因为先编写测试,所以可能出现的问题都被提前发现了;测试覆盖率高,因为后编写代码,因此测试用例基本都能照顾到;保证代码质量。
TDD 的劣势:因为侧重点在于代码,更多是保证某个测试单元没问题,因此无法保证业务流程没有问题;而且需求经常变更,在修改某个功能点之前要先修改测试用例,因此在复杂的项目中工作量很大;测试代码和实际代码可能会出现耦合,经常需要修改。
BDD (Behavior Driven Development) 行为驱动开发
BDD 是从产品角度出发,它鼓励开发人员和非开发人员之间的协作,是一种黑盒测试。
开发流程大致是:获悉需求并编写代码,然后再从用户角度编写集成测试。
BDD 的优势:它的测试重点更多是站在项目角度,在 UI 和 DOM 的角度进行测试,直接地测试业务流程是否没问题,测试代码和实际代码解耦。
BDD 的劣势:因为是集成测试,因此不是那么关注每个函数功能,测试覆盖率比较低,没有 TDD 那么严格的保证代码质量。
vue测试
Vue CLI 拥有开箱即用的通过 Jest 或 Mocha 进行单元测试的内置选项。官方的 Vue Test Utils 提供更多详细的指引和自定义设置。
单元测试:用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。针对一些内部机制的核心逻辑,使用代码进行编写,属于白盒测试。
E2E测试:常见的开发流程里,测试人员不管内部实现机制,只看最外层的输入输出,比如一个加法的页面,会设计N个case,测试加法的正确性,称为E2E测试。端对端测试,属于黑盒测试,通过编写测试用例,自动化模拟用户操作,确保组件间通信正常,程序流数据传递如预期。
集合多个测试过的单元一起测试称之为集成测试。
配置工作
1.新建项目:新建vue项目,手动选择特性,添加Unit Testing和E2E Testing
2.已有项目:
2.1 命令
vue add @vue/cli-plugin-unit-jest
vue add @vue/e2e-nightwatch
2.2 vue ui可视化添加插件
通过 vue ui 启动可视化管理系统,在插件栏,点击 ‘添加插件’,搜索 @vue/cli-plugin-unit-jest,点击安装就可以了,对应命令行的 vue add @vue/cli-plugin-unit-jest 命令;这个过程实际上是包含了安装和调用两个步骤,并且会把相关的依赖一并安装进来,这样就不需要一个一个的安装每个依赖了。
vue ui
单元测试
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。按空间切割,对每个组件进行测试。
在vue中,推荐用Mocha+Chai或者Jest。
Mocha特点:灵活,但是只提供简单的测试结构,如果需要其他功能如assertions, spies,mocks等需要添加其他库/插件完成。
Jest:API更简单,样板代码更少。灵活且容易配置。测试文件彼此隔离执行。高级监控模式。快照支持,测试更容易上手。代码覆盖率。
此处单元测试解决方案选择:Jest
使用
Counter.vue (在src/components/下创建该文件)
<template>
<div>
<div>{{ computedCount }}</div>
<button @click="inc">加</button>
<button @click="dec">减</button>
<button @click="reset">重置</button>
</div>
</template>
<script>
export default {
props: {
factor: { type: Number, default: 1 }
},
data() {
return {
count: 0
};
},
methods: {
inc() {
this.count++;
},
dec() {
this.count--;
},
reset() {
this.count = 0;
}
},
computed: {
computedCount: function() {
return this.count * this.factor;
}
}
};
</script>
Counter.spec.js (在tests/unit下创建该文件)
import { mount } from '@vue/test-utils'
import Counter from '@/components/Counter.vue'
describe("Counter.vue", () => {
it("渲染Counter组件", () => {
const wrapper = mount(Counter)
expect(wrapper.element).toMatchSnapshot()
})
it("初始化之为0", () => {
const wrapper = mount(Counter)
expect(wrapper.vm.count).toEqual(0)
})
it("加1", () => {
const wrapper = mount(Counter)
wrapper.vm.inc()
expect(wrapper.vm.count).toEqual(1)
})
it("减1", () => {
const wrapper = mount(Counter)
wrapper.vm.dec()
expect(wrapper.vm.count).toEqual(-1)
})
it("重置", () => {
const wrapper = mount(Counter)
wrapper.vm.reset()
expect(wrapper.vm.count).toEqual(0)
})
it("因数为10加1操作", () => {
const wrapper = mount(Counter, { propsData: { factor: 10 } })
wrapper.vm.inc()
expect(wrapper.vm.computedCount).toEqual(10)
})
})
运行测试
image.pngRun your tests: npm run test
Lints and fixes files: npm run lint
Run your unit tests: npm run test:unit
打开package.json文件修改"test:unit": "vue-cli-service test:unit"在后面加上--watch这样就只测试发生变动的文件
E2E测试
端对端测试,属于黑盒测试,通过编写测试用例,自动化模拟用户操作,确保组件间通信正常,程序流数据传递如预期。按时间切割,对每个流程进行测试。
项目的搭建,新建 vue-cli 时选择使用 E2E Testing > Nightwatch (selenium-base) (vue 版本为3.3.0)。
典型 e2e 测试框架对比
名称 | 断言 | 是否跨浏览器支持 | 实现 | 官网 | 是否开源 |
---|---|---|---|---|---|
nightwatch | assert和 chai expect | 是 | selenium | http://nightwatchjs.org/ | 是 |
cypress | chai、chai-jQuery等 | 否 | chrome | https://www.cypress.io/ | 是 |
testcafe | 自定义断言 | 是 | 非基于selenium | https://devexpress.github.io/testcafe/ | 是 |
katalon | TDD/BDD | 是 | 未知 | https://www.katalon.com/katalon-studio/ | 是 |
- nightwatch 需要安装配置selenium ,selenium-serve 需要安装 jdk;
- crypress 安装方便,测试写法和单元测试一致,只支持chrome类浏览器,有支持其他浏览器的计划;
- testcafe 安装方便,测试写法和之前的单元测试差异比较大,编写测试用例时只能选择到可见的元素;
- katalon 不是测试框架,是IDE,比较重,并且不开源,测试用例不是用js编写但是可以通过chrome插件录测试用例。
在已有项目添加e2e测试:vue add @vue/e2e-nightwatch
package.json自动注入命令:"test:e2e": "vue-cli-service test:e2e"
命令行参数
Usage: vue-cli-service test:e2e [options]
--url run e2e tests against given url instead of auto-starting dev server
--config use custom nightwatch config file (overrides internals)
-e, --env specify comma-delimited browser envs to run in (default: chrome)
-t, --test specify a test to run by name
-f, --filter glob to filter tests by filename
插件 nightwatch 配置默认运行 chrome,如果e2e测试要在其中浏览器运行,需要在项目根目录下添加 nightwatch.config.js或nightwatch.json 文件配置其他浏览器,将配置合并到内部 nightwatch配置中。
或,可以使用上述 -config 选项将内部配置替换为自定义配置文件。
有关配置选项以及如何设置浏览器驱动程序,阅读 —— http://nightwatchjs.org/gettingstarted/#settings-file
默认文件地址为 项目根目录下 /tests/e2e/specs 下以 .js 结尾的所有文件。
describe('My First Test', () => {
it('Visits the app root url', () => {
cy.visit('/')
cy.contains('li', '语文')
})
})
上面代码,打开浏览器导航到项目运行 url ,等待使元素在页面可见,检测渲染出的页面包含内容为“语文”的li标签。
image.png
cypress
image.png
网友评论