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)