This post will be about my pull request that did some tests with Go.
Here's some backstory about why I chose this repo. I've been contributing to 7tv, but I'm also a member of their discord community. There I noticed a project that uses 7tv that was also written in Go. A small project from someone in the same community - likely to explain stuff and help out, shouldn't be too difficult of an app.
So I reached out. You can look at my previous post how that went. Long story short, I decided to try my newly acquired knowledge of testing in a different language. The one I'm really interested in - GO.
How to test?
I researched some basic stuff, official documentation got me started.
Some specific things I noticed:
- To make a test file, you have to name it NAME_test.go, instead of NAME.test.js compared to JS.
- Go has a built in
testing
package, which makes it simple and universal for any GO unit testing. - The most useful resource I found is (Go by example)[https://gobyexample.com/testing]. Really shows all you need to begin and make it work. Was even easier than JS, honestly. The table example was really useful too.
What I did
I followed author's advice and made tests for humanize
. Those functions have simple string/int input and output. I was happy with how fast I figured things out.
I really a system of testing tables, it looks clean and structured.
You can see that I created variables in my test for arguments and the return value I expect. Then I made a table with those variables united in a single object. That way you can later loop through them and check if that combination works together.
Here's some more code.
- Function to test:
func StringToSeconds(s string) (int, error) {
if strings.HasSuffix(s, "m") {
num := strings.TrimSuffix(s, "m")
integer, err := strconv.Atoi(num)
return integer * 60, err
}
if strings.HasSuffix(s, "s") {
num := strings.TrimSuffix(s, "s")
integer, err := strconv.Atoi(num)
return integer, err
}
integer, err := strconv.Atoi(s)
return integer, err
}
- The testing function itself:
func TestStringToSeconds(t *testing.T) {
var tests = []struct {
str string
want int
}{
{"60s", 60},
{"1m", 60},
{"60m", 3600},//Big example
{"22s", 22},//Basic example
{"", 0},//Empty string
{"10d", 0},//Invalid input
}
for _, tt := range tests{
testname:=fmt.Sprintf("%s", tt.str)
t.Run(testname, func(t *testing.T) {
ans, err:=StringToSeconds(tt.str)
if ans != tt.want {
fmt.Printf("%s",err)
t.Errorf("Got %d, want %d", ans, tt.want)
}
})
}
}
There was finally something I could fix through my testing. I figured out that when this following function returns a value with combined units (minutes and seconds), it returns it in a float format, adding a bunch of .000000
. Not only it looked bad, it also wasn't consistent with other return values which were ints.
func SecondsToString(s int) string {
if s < 60 {
return fmt.Sprintf("%ds", s)
}
if s%60 == 0 {
return fmt.Sprintf("%dm", s/60)
}
floored := math.Floor(float64(s) / 60)
rest := float64(s) - (floored * 60)
return fmt.Sprintf("%fm %fs", floored, rest)
}
This is how it would look with combined values:
So I actually changed something in the original code to match the format!
...
floored := int(math.Floor(float64(s) / 60))
rest := int(float64(s)) - (floored * 60)
return fmt.Sprintf("%dm %ds", floored, rest)
}
Next level: Mocks?
I was content with myself. I did tests that actually worked. Maybe I can make tests for something more difficult?
So my next quest: How do I mock in go? I went to google. There was a problem. I couldn't find a clear and solid answer. So I went on to ask people who might know.
He showed me his repo where he made a bunch of tests, however I couldn't figure it out. So I went in voice to see what he'll explain..
What he showed was.. a lot. Fast. I couldn't follow. He'd jump from document to document, adding in words I didn't know, and I was really too confused to even form a question. Basically...
And then he went on to build his new chair that apparently had wrong instructions.
So I decided I'll postpone my learning about mocks in Go. After all, I had enough to make a PR where things didn't break yet. I still learned new things. Good enough for me.
YAY I DID SOMETHING NEW IN GO
Top comments (0)