0%

GO_Learning_TDD_introduction

Definition

TDD is the abbreviation of Test Drive Development. In my view, that is a kind of develop procedure or develop concept. From the point of develop procedure, TDD can be divided into a circle:

  • Write a test
  • Make the complie pass
  • Run the test, see that it fails and check the error message is meaningful
  • Write enough code to make the test pass
  • Refactor

The circle aboved can be called code flow. In long term, that will help developer.

Goodness

  • Make sure code module is self-contained;
  • Test first make sure you have a clear goal

Badness

  • Tedious

Example

Hello World is a good start to understand TDD producre.

Write a Simple Test

Implement the simplest feature.

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "testing"

func TestHello(t *testing.T) {
got := Hello()
want := "Hello, world"

if got != want {
t.Errorf("got %q want %q", got, want)
}
}

Implement Simple Code Feature

1
2
3
4
5
6
7
8
9
10
11
package main

import "fmt"

func Hello() string {
return "Hello, world"
}

func main() {
fmt.Println(Hello())
}

Run The Test

This part we need to check some points :

  • Write a failing test and see it fail so we know we have written a relevant test for our requirements and seen that it produces an easy to understand description of the failure
  • Writing the smallest amount of code to make it pass so we know we have working software
  • Then refactor, backed with the safety of our tests to ensure we have well-crafted code that is easy to work with

Enrich the test and go back to the first step;

More Complate Test

For Hello World , We want infer Some Name , not just “world”,like “Hello QingZhi”. So we chang the Test file, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func TestHello(t *testing.T) {

assertCorrectMessage := func(t testing.TB, got, want string) {
t.Helper()
if got != want {
t.Errorf("got %q want %q", got, want)
}
}

t.Run("saying hello to people", func(t *testing.T) {
got := Hello("Chris")
want := "Hello, Chris"
assertCorrectMessage(t, got, want)
})

t.Run("empty string defaults to 'World'", func(t *testing.T) {
got := Hello("")
want := "Hello, World"
assertCorrectMessage(t, got, want)
})

}

More Complate Code

Not much word , just look at the feature code:

1
2
3
4
5
6
7
8
const englishHelloPrefix = "Hello, "

func Hello(name string) string {
if name == "" {
name = "World"
}
return englishHelloPrefix + name
}

Run the test again

Check the feature code is suitable with test goal. And Enrich feature again, like add other country language :Chinese “你好, QingZhi”.

Complate Test
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main

import "testing"

func TestHello(t *testing.T) {

assertCorrectMessage := func(t testing.TB, got, want string) {
t.Helper()
if got != want {
t.Errorf("got %q want %q", got, want)
}
}

t.Run("to a person", func(t *testing.T) {
got := Hello("Chris", "")
want := "Hello, Chris"
assertCorrectMessage(t, got, want)
})

t.Run("empty string", func(t *testing.T) {
got := Hello("", "")
want := "Hello, World"
assertCorrectMessage(t, got, want)
})

t.Run("in Spanish", func(t *testing.T) {
got := Hello("Elodie", spanish)
want := "Hola, Elodie"
assertCorrectMessage(t, got, want)
})

t.Run("in French", func(t *testing.T) {
got := Hello("Lauren", french)
want := "Bonjour, Lauren"
assertCorrectMessage(t, got, want)
})

}
Complate Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

package main

import "fmt"

const spanish = "Spanish"
const french = "French"
const englishHelloPrefix = "Hello, "
const spanishHelloPrefix = "Hola, "
const frenchHelloPrefix = "Bonjour, "

// Hello returns a personalised greeting in a given language.
func Hello(name string, language string) string {
if name == "" {
name = "World"
}

return greetingPrefix(language) + name
}

func greetingPrefix(language string) (prefix string) {
switch language {
case french:
prefix = frenchHelloPrefix
case spanish:
prefix = spanishHelloPrefix
default:
prefix = englishHelloPrefix
}
return
}

func main() {
fmt.Println(Hello("world", ""))
}
Run the Final Test

Final part , get the GREAT Hello World.