文章目录
1.题目要求
2.TDD
① TDD 的定义
- TDD 即测试驱动开发(Test-Driven Development),从测试样例入手,先写好测试用例,然后再去写实现,是一种设计方法论
② 为什么用 TDD
- “测试先行”可以提高产品质量,开发人员一边写测试用例,一边编写业务代码来推动项目
- 可以提前了解清楚需求,因为写测试用例的前提是弄懂了需求
- 有着快速的反馈,有丰富的测试用例来覆盖业务代码,一旦代码出错,就可以及时发现问题并改正
③ TDD的设计周期
- 写一个新的测试用例
- 运行新加的测试用例,看到它失败(还没写功能代码)
- 编写业务代码,对开发代码做很小的修改,目的就是让新加的测试通过
- 运行所有的测试用例,然后看到所有测试都通过了
- 移掉重复的代码,对代码进行重构
在学习了Golang的简单语法后,我们来尝试下使用TDD来实现快速排序算法(Quick Sort)
3.编程需求
- 设计一个 QuickSort 函数,实现快速排序算法。
- 具体要求:给定一个整数序列,通过调用 QuickSort 函数能将其排序为数值从小到大
4. TDD编程过程
①先写一个测试用例
- 创建一个工作目录,写下如下测试代码
package quicksort
import "testing"
func TestQuickSort(t *testing.T) {
arr1 := []int{2, 4, 5, 8, 6, 3, 1, 7}
arr2 := []int{2, 4, 5, 8, 6, 3, 1, 7}
res := QuickSort(arr1, 0, 7)
expect := []int{1, 2, 3, 4, 5, 6, 7, 8}
for i := 0; i < 8; i++ {
if res[i] != expect[i] {
t.Errorf("\n result %v\n but expect %v\n given %v", res, expect, arr2)
break
}
}
}
② 尝试运行测试
③ 先使用最少的代码来让失败的测试先跑起来
- 在同一个工作目录下的QuickSort.go中,实现代码
package quicksort
func QuickSort(arr [] int, low, high int) ([]int) {
return arr
}
- 在终端运行 go test 后得到以下结果
④ 把代码补充完整,使得它能够通过测试
- 我们先使用冒泡排序的方式让其通过排序降序测试
package quicksort
func QuickSort(arr [] int, low, high int) ([]int) {
for i := low; i <= high; i++{
for j := i+1; j <= high; j++{
if arr[i] > arr[j] {
arr[i], arr[j] = arr[j], arr[i]
}
}
}
return arr
}
- 测试 go test,提示正确,通过 PASS
⑤ 重构
- 快速排序是分而治之思想在排序算法上的应用。本质上说,快速排序应该算是在冒泡排序基础上的递归分治法
- 从数列中挑出一个元素,作为基准(pivot)
- 重新排序数列,所有元素比基准值小的摆放在基准前面,比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
package quicksort
func partition(arr []int, low, high int) int {
pivot := arr[low]
for low < high {
for low < high && pivot <= arr[high] {
high--
}
arr[low] = arr[high]
for low < high && pivot >= arr[low] {
low++
}
arr[high] = arr[low]
}
arr[low] = pivot
return low
}
func QuickSort(arr [] int, low, high int) ([]int) {
if high > low {
pivot := partition(arr, low, high)
QuickSort(arr, low, pivot-1)
QuickSort(arr, pivot+1, high)
}
return arr
}
- 测试 go test,提示正确,通过 PASS
⑥ 基准测试
-
testing.B 可使你访问隐性命名(cryptically named)b.N
-
基准测试运行时,代码会运行 b.N 次,并测量需要多长时间。
-
代码运行的次数不会对你产生影响,测试框架会选择一个它所认为的最佳值,以便让你获得更合理的结果。
-
在 QuickSort_test.go 中添加基准测试代码
func BenchmarkQuickSort(b *testing.B) {
arr := []int{2, 4, 5, 8, 6, 3, 1, 7}
for i := 0; i < b.N; i++ {
QuickSort(arr, 0, 7)
}
}
- 用 go test -bench=. 来运行基准测试。