Let‘s Go —— Go语言开发之旅(二)

TDD

What is TDD?

TDD是测试驱动开发(Test-Driven Development)的英文简称,是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不只适用于XP(Extreme Programming),同样可以适用于其他开发方法和过程。

Why TDD?

  • “测试先行”可以提高产品质量,开发人员一边写测试用例,一边编写业务代码来推动项目
  • 可以提前了解清楚需求,因为写测试用例的前提是弄懂了需求
  • 有着快速的反馈,有丰富的测试用例来覆盖业务代码,一旦代码出错,就可以及时发现问题并改正

TDD设计周期

  • 写一个新的测试用例
  • 运行新加的测试用例,看到它失败(还没写功能代码)
  • 编写业务代码,对开发代码做很小的修改,目的就是让新加的测试通过
  • 运行所有的测试用例,然后看到所有测试都通过了
  • 移掉重复的代码,对代码进行重构

初识TDD——迭代

与别的编程语言一样,循环和迭代是不可或缺的功能。在 Go 中 for 用来循环和迭代,与别的语言不同之处在于Go 语言没有 while,do,until 这几个关键字,你只能使用 for。

先写测试

首先我们先为我们实现的迭代循环功能编写测试代码

package iteration

import "testing"

func TestRepeat(t *testing.T) {
    repeated := Repeat("a")
    expected := "aaaaaaa"

    if repeated != expected {
        t.Errorf("expected '%q' but got '%q'", expected, repeated)
    }
}

使用最少的代码来让失败的测试先跑起来

接下来我们完成循环迭代功能代码

package iteration

func Repeat(character string) string {
    return "a"
}

并运行测试程序进行测试

go test repeat_test.go

得到了如下结果:
在这里插入图片描述

完善代码,使得它能够通过测试

通过测试回馈信息得知我们的代码功能不正确,需要完善代码

func Repeat(character string) string {
    var repeated string
    for i := 0; i < 7; i++ {
        repeated = repeated + character
    }
    return repeated
}

再次运行测试程序,得到正确的结果
在这里插入图片描述

重构

重构(Refactoring)就是通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性。

为了使repeat程序更加简洁易懂,更加具有维护性,我们在保证功能的前提下重构了代码

const repeatCount = 5

func Repeat(character string) string {
    var repeated string
    for i := 0; i < repeatCount; i++ {
        repeated += character
    }
    return repeated
}

基准测试

基准测试是指通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和可对比的测试。

在现实生活中,实现功能远远不能满足人们的需求。良好的性能也是人们判断该程序是否便利的重要标准。所以,我们需要通过基准测试来测试程序性能。

repeat基准测试

接下来进行repeat的基准测试,基准测试代码如下:

func BenchmarkRepeat(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Repeat("a")
    }
}

运行基准测试

go test -bench .

得到的基准测试结果如下:
在这里插入图片描述

字符拼接基准测试比较

为了更好的对比相同功能不同实现方法的性能比较,我们分别对两种不同的字符拼接程序进行了基准测试

func StrPlus1(a []string) string {
	var s, sep string
	for i := 0; i < len(a); i++ {
		s += sep + a[i]
		sep = " "
	}
	return s
}
func StrPlus2(a []string) string {
	return strings.Join(a, " ")
}

编写基准测试比较StrPlus1和StrPlus2两种不同字符拼接方法的性能

func BenchmarkStrPlus1(b *testing.B) {
	for i := 0; i < b.N; i++ {
		StrPlus1([]string{"xxx", "bbb", "aaa"})
	}
}

func BenchmarkStrPlus2(b *testing.B) {
	for i := 0; i < b.N; i++ {
		StrPlus2([]string{"xxx", "bbb", "aaa"})
	}
}

进行基准测试比较字符拼接算法的效率

go test -bench .

得到的结果如下:
在这里插入图片描述
从结果我们可以分析出StrPlus2的字符拼接效率要高与StrPlus1

TDD实践——快速排序算法

快速排序算法

快速排序算法的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

快速排序算法

先写测试

首先我们先为我们实现的快速排序算法编写测试代码

func TestQuickSort(t *testing.T) {
	arr := []int{2, 4, 8, 5, 3, 6, 1, 7, 9, 0}
	res := QuickSort(arr, 0, 7)
	expected := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

	for i := 0;  i < 8;  i++ {
		if res[i] != expected[i] {
			t.Errorf("\n result %v\n but expect %v\n", res,  expect)
			break
		}
	}
}

使用最少的代码来让失败的测试先跑起来

接下来简单完成代码让测试可以跑起来

func QuickSort(list []int, left int, right int) []int {
    return list
}

并运行测试程序进行测试

go test quicksort_test.go

得到的结果如下:
在这里插入图片描述

完善代码,使得它能够通过测试

接下来完成快速排序算法功能

func partition(nums []int, left int, right int) int {
    value := nums[left]
    for left < right {
        for nums[right] >= value && left < right {
            right--
        }
        nums[left] = nums[right]
        for nums[left] < value && left < right {
            left++
        }
        nums[right] = nums[left]
    }
    nums[left] = value
    return left
}

func QuickSort(list []int, left int, right int) []int {
    if left < right {
        middle := partition(list, left, right)
        QuickSort(list, left, middle-1)
        QuickSort(list, middle+1, right)
    }
    return list
}

再运行测试得到的正确结果如下:
在这里插入图片描述

基准测试

接下来通过基准测试测试快速排序的性能,完成基准测试代码如下:

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 .

得到的基准测试结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值