Managing Pre and Post Steps in Go Tests.

Boluwatife Fakorede
3 min readSep 13, 2023
https://unsplash.com/@danielkcheung

When writing tests in Go, we could have some repetitive steps needed for every test. For example, we are setting up a database for your test, conditional test execution, etc. In Go, an inbuilt test function that can help with this is the “TestMain” function.

TestMain

The TestMain function sounds like it tests the main function of our application, but that is not what it is for. It allows you to execute pre-steps before running tests and post-steps after tests have been completed, enabling you to set up and tear down resources, control test execution conditions, and perform custom actions as needed.

Note: We can only have one TestMain per package since it is a unique test function, and it is also good practice to keep it simple.

Example

For this example, we want to be able to;

  • Build a binary and pass into it some flags to test a CLI tool.

Let’s dive in;

Pre-step build of Binary

By running this function, we are executing a pre-step to build the Binary, which has yet to be ready. We cannot call our tests (since we don’t have any) and need a post-step to clean up afterwards. Let’s add some tests and demonstrate how to run the tests.

Test which executes the Binary with some arguments.

The above test is not the focus of this article, but it demonstrates a need for a binary to execute and pass an argument (“Test”) to the Binary at the execution phase. Looking closely at the test, it uses the file path to the Binary created in the TestMain. That means we can have multiple tests relying on the Binary, and they should work accordingly. Now, we need to update the TestMain function to call our test and add some post-steps, as shown below;

I am running the test and post-step cleanup.

As shown above, we can run our tests simply by calling the “m.Run” function; this returns an exit code (we desire code 0, representing a successful execution). We pass in the exit code from our test run into the “os.Exit” function. We also have a cleaning-up step, which removes the Binary.

What to note is that the cleanup function runs after the test has been executed, meaning the TestMain function is not run for each test but before all of the tests, then it continues its execution by doing all the remaining cleanups.

The final output looks like this;

Building binary
Running tests
=== RUN TestA
--- PASS: TestA (0.45s)
PASS
Cleaning up

We have successfully used a pre-step and a post-step for the tests.

Thank you for reading.

--

--

Boluwatife Fakorede

A frontend developer, while at that, just a curious cat that loves to share what he knows.