TDD in GoLang
✅ Test Function
t *testing.T
t.Errorf
:%q
,%s: string
,%d: integer
,%v: generic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func TestHello(t *testing.T) { //t is pointer to testing.T
got := Add(1, 2)
want := 3
if got != want {
t.Errorf("expected %d, but got %d", got, want)
}
}
func TestHello(t *testing.T) {
t.Run("Subtest1", func(t *testing.T)){
//test code
}
t.Run("Subtest2", func(t *testing.T)){
//test code
}
}
✅ ExampleTest
- simply test
Add()
function withExampleAdd()
- need
//Output : 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func ExampleAdd() {
sum := Add(1, 5)
fmt.Println(sum)
// Output: 6 //need comment to execute ExampleAdd
}
func TestAdder(t *testing.T) {
sum := Add(2, 3)
expected := 5
if sum != expected {
t.Errorf("expected %d, but got %d", expected, sum) //%d print int
}
}
✅ Benchmark
- Benchmark gives access to loop function
b *testing.B
- 👍🏻 For loop testing
- measure how long it takes to loop
1
2
3
4
5
func BenchmarkRepeat(b *testing.B) {
for b.Loop() {
Repeat("a", 5)
}
}
✅ Helper function in test
- when same code is used in test several times, create a
helper function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func TestHello(t *testing.T) {
t.Run("subtest1", func(t *testing.T) {
//same code needs to be run
assertCorrectMessage(t, got, want)
})
t.Run("subtest2", func(t *testing.T) {
//same code needs to be run
assertCorrectMessage(t, got, want)
})
}
func assertCorrectMessage(t testing.TB, got, want string) {
t.Helper() //tell suite this method is a helper
if got != want {
t.Errorf("got %q want %q", got, want)
}
}
✅ Assign helper function to variable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func TestSumAllTails(t *testing.T) {
checkSums := func(t testing.TB, got, want []int) {
t.Helper() //helper function
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v want %v", got, want)
}
}
t.Run("subtest1", func(t *testing.T) {
//same code needs to be run
checkSums(t, got, want)
})
t.Run("subtest2", func(t *testing.T) {
//same code needs to be run
checkSums(t, got, want)
})
}
✅ Interface and anonymous struct in TDD
If testing same method on several interface, can implement
anonymous struct
- 👎🏻 Before, without
anonymous struct
- rectangle and circle implement
shape
interface
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
func TestArea(t *testing.T) {
checkArea := func(t testing.TB, shape Shape, want float64) {
t.Helper()
got := shape.Area()
if got != want {
t.Errorf("got %g want %g", got, want)
}
}
//👎🏻 similar test code for both rectangle, circle
t.Run("rectangle", func(t *testing.T) {
rectangle := Rectangle{7.0, 6.0}
want := 42.0
checkArea(t, rectangle, want)
})
t.Run("circle", func(t *testing.T) {
circle := Circle{10.0}
want := 314.1592
checkArea(t, circle, want)
})
}
- 👍🏻 after, with
anonymous struct
- create
[]struct
of shape interface - make
t.Errorf
message helpful
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func TestArea(t *testing.T) {
areaTests := []struct {
name string
shape Shape
want float64
}{
{name: "Rectangle", shape: Rectangle{width: 12, height: 6}, want: 72.0},
{name: "Circle", shape: Circle{diameter: 10}, want: 314.1592},
{name: "Triangle", shape: Triangle{width: 12, height: 6}, want: 36.0},
}
for _, tt := range areaTests {
got := tt.shape.Area()
if got != tt.want {
t.Errorf("%v got %g want %g", tt.name, got, tt.want) //Rectangle got 6 want 72
}
}
}
✅
✅
✅
✅
✅
✅
✅
✅
This post is licensed under CC BY 4.0 by the author.