I Underestimated the Importance of Testing…

After all the additions, changes and tools we worked with in regards to our link checking tools over this semester we have finally arrived to automated testing. Unit tests are by no means something new to me, but I never bothered implementing them into my own projects as I never really deemed them necessary (only since I use them personally, they fulfill my needs and I don’t share them on Github either). But now after this lab… I think I should write tests regardless of what project I’m working on.

Since WISA is written in Go, I went with the native testing package that comes bundled with the language, I like keeping things simple and working with the language in a “pure” state is something I try to prioritize within reason of course. Setting up the tests we’re fairly simple and following the guide linked in lab 8 gave me a leg up in getting started. It was as simple as importing the testing package and then setting up functions with the Test prefix which takes a *testing.T parameter which you use to log the tests when asserting their results.

This is what one of my tests look like:

package utils

import (
	"testing"
)

func TestIgnoreURL(t *testing.T) {
	data := []string{"http://abc.com", "http://abc.ca", "http://abc.net"}
	ignoreData := []string{"http://abc.com", "http://abc.ca"}
	expectedData := []string{"", "", "http://abc.net"}

	validUrls := IgnoreURL(data, ignoreData)

	for i, link := range validUrls {
		if link != expectedData[i] {
			t.Errorf("IgnoreURL was incorrect, received %s, want %s", link, expectedData[i])
		}
	}
}

Now as I was writing these tests I realized even more just how bad of a decision it was to write my tool like a script because after modulating the functions I made into packages it made them an extreme pain to work with and extremely nonviable for use in other projects and if I had even an ounce of motivation I’d rewrite the whole thing to avoid the mistakes I made. It mostly boils down to using global variables within the package functions (disgusting) and extremely unfeasible parameters that must be passed to certain functions. I did come across a small bug where status codes were never changed when checking links as I never used them in my program except in testing for verification which prompted me to fix it.

Once I wrote my initial set of tests, I checked the coverage of my code by writing the coverage profile to a file and then viewing it with the HTML go tool I describe in my contributing here. I looked at what wasn’t covered and adjusted my tests to cover them, in the end I ended up with a code coverage of 94.2% of all statements in my utils package. The only pathways I didn’t check we’re errors that would terminate the program from within the function which is another mistake I should have avoided.

A verbose run of all my tests in utils_test.go

As seen in the image above, I used the httpstat.us site for testing for the network mock tests although I think a local solution would be much better similar to what Tony did for their project.

After I was done with tests I created an action CI workflow and used the default boilerplate provided by Github for Go projects as it used everything I used so I didn’t need to change anything (yay pure Go) and once I updated my contributing guidelines I saw my CI tests passed, the only thing I couldn’t integrate was goreturns for linting as it seems you need to write a bash script to properly lint Go projects and I decided it was a little over my head for the moment as I need to focus on other classes too.

Since Tony added a test for the duplicate link removal functionality of my project I decided to contribute to their project as well but I saw that everything was fairly well covered, so I used the HTML tool after writing the coverage profile of the project to a file to see what wasn’t covered and I saw that the checking of links with 403 and other statuses that weren’t deemed “good” or “bad” aren’t being covered so, I wrote a test for just that. After pushing the unit test and creating a PR my test passed the CI checks setup for the project and that was the end of that.

So yeah, testing is useful… It was a huge slap in the face writing tests because I saw clearer than before what I should have avoided but it was a welcome slap because now I will be more vigilant to these mistakes so I can avoid them and (hopefully) write better code.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create your website with WordPress.com
Get started
%d bloggers like this: