The testing feature you’ve been missing in pure Go / Golang
If you’ve started writing automation tests in Go after switching from another programming language like me, even there is no matter whether you’re an apologist of Java, C#, Python, JS etc — I bet you’ve been missing some test runner features here in Go like setting up pre-conditions before the entire Test Suite execution and cleaning up the data afterwards. Or performing the same setup/cleanup actions for each and every Test and avoiding of applying viral anti-pattern called Copy-paste programming.
I bet this article and the solution below that’s what you’ve been looking for so long!
TL;DR
All code snippets used in the article are in my Github gist here
Go has built-in test runner which is nothing but testing pkg, so there is no need to pull up a separate framework/library like in another programming languages.
Important! All code snippets should be put inside of the ~/tests dir!
BeforeSuite & AfterSuite
Let’s build the mechanism which will be invoked before and after the entire Test Suite execution.
Firstly, let’s create certain functions for needed actions:
For the invocation of functions implemented above we’ll be using the power of pure Go itself — TestMain() function. Create a func with the following signature:
func TestMain(m *testing.M) {}
Filling it up:
BeforeEach & AfterEach
As you might know, Go doesn’t have annotations mechanism at all, unlike Java, C# and others. So we’re restricted a bit, but that won’t prevent us from maturing the capabilities and power of the testing possibilities here in Go!
Let’s create some fake dummy functions (like we’ve created above) which will be invoked before and after each and every Test function aka Test scenario.
Now we gonna implement a crucial stuff over here — a function, which will take two params of a func type and will return a func with the func param inside. Sound a bit complicated, yeah? Nothing hard, just have a peek at the function below:
Now we need to declare a var to assign the forEach() func with passing created functions above into it:
var Run = forEach(beforeTest, afterTest)
Putting it all together
The last step is to create a handful test cases with usage of Run variable (with before&after each func wrapped inside) to check out the code. Let’s fail the TestC() function deliberately to get an evidence that the afterEach part will be invoked in case of failure as well.
Now we’re all set to run it via Terminal using go test command and see the results:
This function is invoked BEFORE the entire testing suite!
=== RUN TestAThis is a pre-condition executed BEFORE each Test!This is a TestA() test caseThis is a post-condition executed AFTER each Test!
--- PASS: TestA (0.00s)
=== RUN TestBThis is a pre-condition executed BEFORE each Test!This is a TestB() test caseThis is a post-condition executed AFTER each Test!
--- PASS: TestB (0.00s)
=== RUN TestCThis is a pre-condition executed BEFORE each Test!This is a TestC() test caseThis is a post-condition executed AFTER each Test!
--- FAIL: TestC (0.00s)FAILThis function is invoked AFTER the entire testing suite!Process finished with the exit code 1
Awesome! Everything works as intended! We expected the exact output!
Again, source code demonstrated in the article is HERE
Thank you note
Thanks for the reading/viewing/listening the article, I hope my solution is a useful one and applicable for you.
Feedbacks and subscriptions are appreciated!
Also, I’d invite you to check out another articles from myself: