In this article, you will learn how to quickly set up a test-driven environment to perform a Christmas tree kata in Go.
The rules of this kata are:
Draw a Christmas tree with ASCII characters, the height of the tree should be specifiable.
Example of a tree with a height of 3:
X
XXX
XXXXX
|
Example of a tree with a height of 5:
X
XXX
XXXXX
XXXXXXX
XXXXXXXXX
|
Project setup
Create a new Go module:
go mod init kata
Create the main source file:
touch main.go
package main
func DrawTree() {
// TODO: add implementation here
}
TDD setup
Install Testify:
go get github.com/stretchr/testify
Create the test file:
touch main_test.go
package main
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestDrawTree(t *testing.T) {
// TODO: add tests here
assert.Equal(t, 2, 1+1)
}
To run tests automatically when source files are changed:
watchman-make -p '**/*.go' --make=go -t test
To run tests manually:
go test
Example tests and implementations
Draw a trunk
Test:
func TestDrawTree(t *testing.T) {
// Draw a trunk
/*
|
*/
// Draw a trunk
assert.Equal(t, "|", DrawTree())
}
Implementation:
func DrawTree() string {
tree := "|"
fmt.Println(tree)
return tree
}
Height of 1
Test:
// Height of 1
/*
X
|
*/
assert.Equal(t, "X\n|", DrawTree(1))
Implementation:
package main
import "fmt"
func DrawTree(height int) string {
tree := ""
if height == 1 {
tree += "X"
tree += "\n"
}
tree += "|"
fmt.Println(tree)
return tree
}
Height of 2
Test:
// Height of 2
/*
X
XXX
|
*/
assert.Equal(t, " X\nXXX\n |", DrawTree(2))
Implementation:
func DrawTree(height int) string {
tree := ""
if height == 1 {
tree += "X"
tree += "\n"
}
if height == 2 {
tree += " "
tree += "X"
tree += "\n"
tree += "XXX"
tree += "\n"
tree += " "
}
tree += "|"
fmt.Println(tree)
return tree
}
Height of 3
At this point, we can start to refactor our implementation.
Test:
// Height of 3
/*
X
XXX
XXXXX
|
*/
assert.Equal(t, " X\n XXX\nXXXXX\n |", DrawTree(3))
Implementation:
package main
import (
"fmt"
"strings"
)
func DrawTree(height int) string {
tree := ""
if height > 0 {
for line := 0; line < height; line++ {
tree += strings.Repeat(" ", height-line-1)
tree += strings.Repeat("X", 2*line+1)
tree += "\n"
}
tree += strings.Repeat(" ", height-1)
}
tree += "|"
fmt.Println(tree)
return tree
}