Writing Tests with the testing Package
In this page:
Writing a Basic Test
A test function is named TestXxx, takes a *testing.T, and calls t.Errorf (or t.Fatalf) when an expected result doesn't match the actual one. Here the same check is demonstrated directly in main so it can run and print output.
Note: Since Judge0 runs a single main.go, this example simulates test logic inside main() to show the assertion pattern -- real tests live in a _test.go file run via 'go test'.
Example: Writing a Basic Test
package main
import "fmt"
func add(a, b int) int {
return a + b
}
func main() {
got := add(2, 3)
want := 5
if got != want {
fmt.Printf("FAIL: add(2,3) = %d, want %d\n", got, want)
} else {
fmt.Println("PASS: add(2,3) =", got)
}
}
Login to try C/C++/Java/PHP code in the editor
Table-Driven Tests
A table-driven test defines a slice of input/expected-output cases and loops over them, running the same assertion logic for each -- the idiomatic Go way to cover many cases without duplicating test code.
Example: Table-Driven Tests
package main
import "fmt"
func square(n int) int {
return n * n
}
func main() {
cases := []struct {
input, want int
}{
{2, 4},
{3, 9},
{5, 25},
}
for _, c := range cases {
got := square(c.input)
status := "PASS"
if got != c.want {
status = "FAIL"
}
fmt.Printf("%s: square(%d) = %d\n", status, c.input, got)
}
}
Login to try C/C++/Java/PHP code in the editor
Errorf vs Fatalf
t.Errorf marks the test as failed but lets it keep running (useful for reporting multiple issues in one test), while t.Fatalf marks it failed and immediately stops that test function, useful when continuing would panic.
Example: Errorf vs Fatalf
package main
import "fmt"
func divide(a, b int) (int, bool) {
if b == 0 {
return 0, false
}
return a / b, true
}
func main() {
if _, ok := divide(10, 0); !ok {
fmt.Println("caught invalid division, stopping this check (like t.Fatalf)")
}
fmt.Println("continuing with other checks (like t.Errorf would allow)")
}
Login to try C/C++/Java/PHP code in the editor
- Naming a test function without the exact Test prefix (and capitalized), which 'go test' won't discover and run.
- Forgetting a test function must take exactly one parameter, *testing.T, or it won't be recognized as a valid test.
- Using t.Fatal inside a goroutine spawned by a test, which is unsafe -- t methods must be called from the test's own goroutine.
- Test functions live in _test.go files and are named TestXxx, taking a *testing.T parameter.
- t.Errorf reports a failure but lets the test continue; t.Fatalf reports a failure and stops immediately.
- 'go test' automatically discovers and runs every TestXxx function in a package.
- Table-driven tests, iterating over a slice of input/expected pairs, are the idiomatic Go testing style.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: