Skip to content

testing: panic in a subtest doesn't execute any deferred funcs outside of the subtest #20394

@blinsay

Description

@blinsay

What did you do?

I've been writing myself some test helpers to set up/tear down some expensive database state and noticed when my tests panicked the tear down wouldn't get run. Eventually, I realized that subtests won't run any defered funcs that were set up before the subtest.

package main

import (
	"fmt"
	"testing"
)

func TestRunPanic(t *testing.T) {
	defer func() {
		fmt.Println("outer deferred")
	}()

	t.Run("subtest", func(t *testing.T) {
		defer func() {
			fmt.Println("inner deferred")
		}()

		panic("boom")
	})
}

I'd expect this example to run both defered funcs, but when running it, this is the output I see.

$ go test -v .
=== RUN   TestRunPanic
=== RUN   TestRunPanic/subtest
inner deferred
panic: boom [recovered]
	panic: boom

This was pretty surprising to me! After looking through the source of t.Run it makes sense, given that the test/panic is being run in a separate goroutine, but the docs for sub-tests and sub-benchmarks don't seem to mention that.

What version of Go are you using (go version)?

go version go1.8.1 darwin/amd64

What operating system and processor architecture are you using (go env)?

GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions