ProgramGuru

Testing Concurrent Programs

Start with Testing Concurrent Programs

In this lesson, explore testing concurrent programs through one small Go program, and connect its output to the language rules behind it.

What you’ll learn

  • Explain the main purpose of testing concurrent programs.
  • Read and run the complete Go example in this lesson.
  • Apply the concept and recognize common mistakes.

Understand the idea

Concurrent tests should verify outcomes and shutdown behavior rather than assume workers run in a fixed order. Use synchronization, cancellation and time bounds to prevent tests from hanging indefinitely.

Run go test -race as an additional signal, and avoid time.Sleep as a substitute for waiting on an event.

Visualize how it works

Follow this diagram before executing the example. Check where a value or decision changes what runs next.

Visual explanation for concurrent testsSynchronization belongs in the code and its tests.Start workersStep 1Join workersStep 2Assert stable resultStep 3Run -raceStep 4Synchronization belongs in the code and its tests.
Synchronization belongs in the code and its tests.

Tools, syntax and practical notes

concurrent_test.go

package main
import (
    "reflect"
    "testing"
)
func TestConcurrentSquares(t *testing.T) {
    got := concurrentSquares([]int{2,3,4})
    if !reflect.DeepEqual(got, []int{4,9,16}) { t.Fatalf("got %v",got) }
}

Run go test -race ./....

Run a complete Go example

This example is a complete program. Save it as main.go or paste it into the Go Playground.

Go code

package main

import (
	"fmt"
	"sync"
)

func concurrentSquares(nums []int) []int {
	result := make([]int, len(nums))
	var wg sync.WaitGroup
	for i, n := range nums {
		wg.Add(1)
		go func(index, value int) { defer wg.Done(); result[index] = value * value }(i, n)
	}
	wg.Wait()
	return result
}
func main() { fmt.Println(concurrentSquares([]int{2, 3, 4})) }

Output

[4 9 16]

Trace what the program does

Several goroutines write different result indexes. Wait ensures a completed result before returning, so [4 9 16] is deterministic.

Avoid common mistakes

  • A race detector reports observed races, not logical deadlocks that never run.
  • Tests should not assume worker scheduling or completion order.

Try it yourself

Add a TestConcurrentSquares that compares the returned slice and run it with -race.

Tip: Edit the example above, predict the output, and run the modified code to test your reasoning.

Check your understanding

What should a concurrent unit test assert?
Choose one answer. You can try again.

Answer and explanation

Correct outcome and proper synchronization

Correct. Several goroutines write different result indexes.

What you should remember

You have practiced Testing Concurrent Programs in a small, self-contained program. The important habit is to predict what runs, inspect the actual output and distinguish the language rule from the particular example.

Before continuing, make sure you can explain the program to someone who has not seen it, including the line that changes its result.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Code Formatting with gofmt →