Following the Learn Go with Tests guide, starting with a Hello World example that demonstrates Go’s syntax, testing approach, and basic development workflow.
Getting Started with Go #
Go is a programming language developed by Google. Tests are written using the built-in testing package without requiring external frameworks.
Setting Up the Project #
First, let’s create a simple Go module go mod init <modulepath>. In Go, every project starts with a go.mod file:
module example.com/hello
go 1.25.5This creates a module named example.com/hello using Go version 1.25.5. The module name doesn’t need to be a real URL for local projects.
Hello World #
Simple hello.go file that demonstrates Go’s basic syntax and features:
package main
import "fmt"
const spanish = "Spanish"
const french = "French"
const spanishHelloPrefix = "Hola, "
const englishHelloPrefix = "Hello, "
const frenchHelloPrefix = "Bonjour, "
func Hello(name string, language string) string {
if name == "" {
name = "World"
}
prefix := greetingsPrefix(language)
return prefix + name
}
func greetingsPrefix(language string) (prefix string) {
switch language {
case spanish:
prefix = spanishHelloPrefix
case french:
prefix = frenchHelloPrefix
default:
prefix = englishHelloPrefix
}
return
}
func main() {
fmt.Println(Hello("Roman", ""))
}Package Declaration: Every Go file starts with a package declaration. The main package is special, it creates an executable program.
Constants: Go uses const for immutable values.
Functions: Go functions are declared with func. The return type comes after the parameter list: func Hello(name string, language string) string
Named Return Values: In greetingsPrefix, we use a named return value (prefix string). This creates a variable called prefix that we can modify and return implicitly with just return.
Hello World Tests #
Go includes a testing package in the standard library. Test files end with _test.go:
package main
import "testing"
func TestHello(t *testing.T) {
t.Run("saying hello to people", func(t *testing.T) {
got := Hello("Roman", "")
want := "Hello, Roman"
assertCorrectMessage(t, got, want)
})
t.Run("say 'Hello, World' when an empty string is supplied", func(t *testing.T) {
got := Hello("", "")
want := "Hello, World"
assertCorrectMessage(t, got, want)
})
t.Run("in spanish", func(t *testing.T) {
got := Hello("Elodie", "Spanish")
want := "Hola, Elodie"
assertCorrectMessage(t, got, want)
})
t.Run("in french", func(t *testing.T) {
got := Hello("Elodie", "French")
want := "Bonjour, Elodie"
assertCorrectMessage(t, got, want)
})
}
func assertCorrectMessage(t testing.TB, got, want string) {
t.Helper()
if got != want {
t.Errorf("got %q want %q", got, want)
}
}Test Functions: Test functions must start with Test and take a *testing.T parameter.
Subtests: t.Run() creates subtests to organize related test cases and show which specific case failed.
Helper Functions: The assertCorrectMessage function uses t.Helper() to mark itself as a test helper. When tests fail, the error points to the calling test rather than the helper function.
Error Reporting: t.Errorf() reports test failures with formatted output. The %q verb adds quotes around strings to show whitespace differences.
Running Tests #
go test ./... # Run all tests in current directory and subdirectories
go test -v # Run tests with verbose output
go test -cover # Run tests and show coverage
go test -run TestHello # Run specific test functionDevelopment Tools #
# Documentation
go doc fmt
# Local documentation server
go install golang.org/x/pkgsite/cmd/pkgsite@latest
pkgsite -open .
# Test runner
go install gotest.tools/gotestsum@latest