# 好书推荐:使用测试驱动开发的方式学习go语言




首先这本书是免费的。

其次这本书是开源的。

如果你想学习go和TDD（测试驱动开发）的话，这本书是不错的选择。

就个人经历而言，学习go语言目前比较好的材料是https://gobyexample.com，通过例子学习go语言，事半功倍。

而这本使用测试驱动开发的方式学习go语言内容则更为立体，非常适合大家在学习go语言的同时也对测试驱动开发有一定的了解。

### 什么是测试驱动开发

概念很大，简单来说，测试驱动开发是一种精神，就是先写用例再写实现代码的精神。

测试驱动开发其实是这样工作的

1. 先写单元测试用例，测一个不存在的功能或者函数
2. 运行单元测试用例，如果失败，则修改实现，直到测试用例通过
3. 添加更多的测试用例
4. 重复步骤2,3并进行重构，直到所有的功能都测试用例并且用例都运行通过


### 书上的例子

通过书上的例子可以对上面的步骤有一个感性的认识。

比如实现一个加法的函数，我们可以先写测试用例去测试这个函数，这个函数的名字是Add(int,int)，这是步骤1

```
package integers

import "testing"

func TestAdder(t *testing.T) {
    sum := Add(2, 2)
    expected := 4

    if sum != expected {
        t.Errorf("expected '%d' but got '%d'", expected, sum)
    }
}
```

接着运行用例，此时自然是会失败，因为Add()函数我们并未实现。错误如下:

```
./adder_test.go:6:9: undefined: Add

```

接下来实现Add()函数，以便让用例可以通过，这里有个规则，就是不要过度实现。

只为测试的运行编写最少量的代码并检查失败测试的输出。

比如你会看到这样的我们的实现是这样的

```
package integers

func Add(x, y int) int {
    return 0
}
```
这可以让我们的代码编译通过，这样就可以看到到底是哪个用例出了什么问题了

```
adder_test.go:10: expected '4' but got '0'
```

下面编写足够的代码使其通过。

```
func Add(x, y int) int {
    return 4
}
```

呃！！！！你这是在开玩笑吗？这样可以吗？

这样真的可以。

很明显，现在测试用例是通过的，我们Add()方法也工作的很好，这是满足需求的，不是吗？

好吧，下面就有意思了。再增加一个测试用例

```
func TestAdder(t *testing.T) {
    sum := Add(2, 2)
    expected := 4

    sum1 := Add(3, 5)
    expected1 := 8

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

    if sum1 != expected1 {
        t.Errorf("expected '%d' but got '%d'", expected, sum)
    }
}
```
运行会报错，所以我们单纯return 4的实现是不对的，因为不够灵活，没能cover到大部分的场景。

那么就重构吧。

```
func Add(x, y int) int {
    return x + y
}

```

现在所有的用例都可以通过了。

那么Add()函数的实现也就差不多了。


### 如何学习

把书上的代码按顺序抄一遍并运行起来。

特别是重构的部分，有时候会显得很麻烦，不过这个麻烦的地方往往是精华。

项目地址：https://github.com/quii/learn-go-with-tests

中文版本：https://studygolang.gitbook.io/learn-go-with-tests/




原始封面

![课程图片](https://images.unsplash.com/photo-1422493757035-1e5e03968f95?w=300)


