How to Test Goroutines in Go

Testing goroutines in Go can be challenging because they execute in a random order. Learn how to test goroutines in Go using just the standard library.

Jose Sitanggang
6 min readApr 9, 2024

Goroutines are one of the most powerful features in Go. They allow us to run tasks concurrently and are also lightweight compared to threads. However, testing goroutines can be challenging because they execute in a random order. Sometimes, the test may finish before the goroutine completes, causing the test to fail intermittently. In this article, we’ll explore how to test goroutines in Go using just the standard library.

Let’s consider this simple example:

// task_runner.go
type Task func(ctx context.Context, args []string)

type TaskRunner struct {
log *slog.Logger
tasks []Task
}

func NewTaskRunner(l *slog.Logger, tasks ...Task) *TaskRunner {
return &TaskRunner{log: l, tasks: tasks}
}

func (r *TaskRunner) Run(ctx context.Context, args []string) {
r.log.InfoContext(ctx, "Run tasks", "args", args)
ctx = context.WithoutCancel(ctx)
for _, task := range r.tasks {
go task(ctx, args)
}
}

The Run methods run tasks concurrently and then forget about them. This kind of problem is often found in real-world applications. For example, when sending emails to multiple recipients, using goroutines allows us to send the emails concurrently, making the process faster.

--

--