课程名称:web前端架构师
课程章节:第11周 第五章
主讲老师:张轩
课程内容:了解 TDD 这种开发方式,掌握 TDD 开发的整个过程
什么是TDD
TDD 指的就是测试驱动开发(Test Driven Development)
- 先根据需求写测试用例
- 完成测试用例后,此时所有测试用例都是失败的
- 实现需求
- 让所有测试用例通过测试
之前都是先实现需求,然后再写测试用例,TDD这种开发方式正好相反
下面使用TDD开发方式,实现一个 ColorPicker 组件
根据需求编写测试用例
- 组件是否正常渲染
- 首先需要一个颜色选择器,点击选择后,可以修改颜色值,选择颜色后还要向父组件发送一个change 事件
- 默认会展示几个颜色列表,点击颜色也可以改变颜色值,同时需要向父组件发送一个change 事件
组件是否正常渲染
- 判断 input type = color 是否存在
- 判断input 的默认值是否是通过props 传递的值
- 判断颜色列表是否存在,其中最后一个是透明色, class 为 transparent-back
it('should render correct', async () => {
expect(wrapper.find('input').exists()).toBeTruthy()
const inputEl = wrapper.get('input').element
expect(inputEl.type === 'color').toBeTruthy()
expect(inputEl.value === '#ffffff').toBeTruthy()
expect(wrapper.findAll('.picked-color-list>li').length).toBe(defaultColors.length)
const firstColorItem = wrapper.get('.picked-color-list>li:first-child div').element as HTMLElement
expect('#' + rgbHex(firstColorItem.style.backgroundColor)).toBe(defaultColors[0])
const lastColorItem = wrapper.get('.picked-color-list>li:last-child div').element as HTMLElement
expect(lastColorItem.classList.contains('transparent-back'))
})
选择器是否可以正常修改色值,修改后向父组件发送change事件
- 修改选择器的值,判断值是否修改
- 修改后是否向父组件发送 change 事件
- 发送change 事件传递的值是否是修改选择器的值
it('should send the correct event when chage input', async () => {
const input = wrapper.get('input')
const color = '#000000'
await input.setValue(color)
expect(wrapper.emitted()).toHaveProperty('change')
const events = wrapper.emitted('change') as string[]
expect(events[0]).toEqual([color])
})
点击颜色列表,是否可以正常修改色值
- 获取到所有的色值列表
- 遍历每一个元素,并给每个元素都触发点击事件
- 点击颜色列表中的每一项元素,判断修改的色值是否是所点击元素对应的背景颜色
it('should send the correct event when click color list', async () => {
const pickedColors = wrapper.findAll('.picked-color-list>li')
for (let i = 0; i < pickedColors.length; i++) {
await pickedColors[i].trigger('click')
const events = wrapper.emitted('change') as string[]
expect(events[events.length - 1]).toEqual([defaultColors[i]])
}
})
实现需求
边写完测试用例后,根据测试用例的每个步骤来编写代码的实现,实现过程就会变得非常简单
实现后,将所有测试用例跑通
<script setup lang="ts">
withDefaults(defineProps<{
value: string
defaultColors?: string[]
}>(), {
defaultColors: () => ['#ffffff', '#409eff', '#000000', '']
})
const emits = defineEmits<{(e: 'change', value: string):void}>()
function changeColor (value: string) {
emits('change', value)
}
</script>
<template>
<div class="color-picker">
<div>
<input
type="color"
:value="value"
@input="changeColor(($event.target as HTMLInputElement).value)"
>
</div>
<ul class="picked-color-list">
<li
v-for="item in defaultColors"
:key="item"
@click.prevent="changeColor(item)"
>
<div
:style="{backgroundColor: item}"
class="color-item"
:class="{'transparent-back': item===''}"
/>
</li>
</ul>
</div>
</template>
使用TDD 的动机
- 当我们开发过程中,我们所做的测试不够时,就会压力就会增大,这个我是深有体会,采用 TDD 开发就会解决很好的解决问题。
- 采用 TDD 还可以将我们编程过程任务化,根据任务编写代码,对开发目标更加清晰(测试驱动开发)