Episode #18— Test Driven development in Golang

Stephens Xu
Fullstack Network
Published in
2 min readJun 8, 2017

--

In this session we worked on refactoring the gong browse and gong comment feature of Gong. Commits here:

I think what’s worth blogging about is really our disciplined Test Driven Development process here. Both Avi and me are big believers of TDD(well, he convinced me most of it anyhow).

Back in Ruby TDD was easy. Now in Golang, I’ve thrilled to find out that TDD is still as powerful and effective.

The two library we used the most are go-check and testing package.

We can import both in our test file like so:

import (
. "gopkg.in/check.v1"
"testing"
)

The testing package offers supports for automated testing when being used in combination of the go test command. Basically, if you add Test in front of the function it would be able to detect thats a test and execute accordingly:

func TestXxx(*testing.T)

For example, in our gong browse feature, we have a git branch name as the input string and an URL as output string. Before we start implementing the function, we would write the test first:

func (s *JiraClientSuite) TestBrowseWithCorrectConfig(c *C) {
config := map[string]string{
"domain": "https://fake.atlassian.net",
}

jiraClient := &JiraClient{
config: config,
}

url, err := jiraClient.Browse("feature/FAKE-1111-something-something")
c.Assert(err, Equals, nil)
c.Assert(url, Equals, "https://fake.atlassian.net/browse/FAKE-1111")
}

The c.Assert syntax sets expectation and will compare result with expectations. As shown, we expect jiraClient.Browse to take a string argument and out put two variables, an url and err. If the function works correctly, error should be nil and url should be in expected format. Now we’ve written some test suits to define what our feature is suppose to do, then we go ahead and implement it:

func (j *JiraClient) Browse(branchName string) (string, error) {
re := regexp.MustCompile(`([A-Z]+-[\d]+)`)
matches := re.FindAllString(branchName, -1)

domain, ok := j.config["domain"]

if !ok {
return "", errors.New("Could not locate domain in config")
}

if len(matches) == 0 {
return "", errors.New("Could not find issue id regex in the branch name")
}

issueId := matches[0]

url := fmt.Sprintf("%s/browse/%s", domain, issueId)

return url, nil
}

Once we’re done implementing, then command line do

go test

Any error in our implementation would be exposed right away, and then we can fix them one by one. When the test passed we’ll know our function is working properly.

TDD is very powerful, but for me personally it’s one of the best sleep aid(better than Advil pm) I can get as an engineer. I just sleep better knowing I have test coverage and my tests are passing.

Hope you find TDD helpful as well :)

Join us for our streaming tonight!

--

--