diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 08796ae..be8b4af 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -7,8 +7,8 @@ jobs:
     strategy:
       matrix:
         go_version:
-          - "1.19"
           - "1.20"
+          - "1.21"
     steps:
       - uses: actions/checkout@v4
       - name: Setup Go
@@ -28,6 +28,7 @@ jobs:
           - "1.18"
           - "1.19"
           - "1.20"
+          - "1.21"
     steps:
       - uses: actions/checkout@v4
       - name: Setup Go
diff --git a/assert/assertion_format.go b/assert/assertion_format.go
index 53f9c8e..896cc7f 100644
--- a/assert/assertion_format.go
+++ b/assert/assertion_format.go
@@ -657,10 +657,12 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string,
 	return NotSame(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
-// NotSubsetf asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
+//	assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted")
+//	assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
 func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -744,10 +746,11 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg
 	return Same(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
-// Subsetf asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subsetf asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
+//	assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted")
+//	assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
 func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go
index 5a2974b..8aaa259 100644
--- a/assert/assertion_forward.go
+++ b/assert/assertion_forward.go
@@ -1306,10 +1306,12 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri
 	return NotSamef(a.t, expected, actual, msg, args...)
 }
 
-// NotSubset asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubset asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
+//	a.NotSubset([1, 3, 4], [1, 2])
+//	a.NotSubset({"x": 1, "y": 2}, {"z": 3})
 func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1317,10 +1319,12 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
 	return NotSubset(a.t, list, subset, msgAndArgs...)
 }
 
-// NotSubsetf asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
+//	a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted")
+//	a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
 func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1480,10 +1484,11 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string,
 	return Samef(a.t, expected, actual, msg, args...)
 }
 
-// Subset asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subset asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
+//	a.Subset([1, 2, 3], [1, 2])
+//	a.Subset({"x": 1, "y": 2}, {"x": 1})
 func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1491,10 +1496,11 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
 	return Subset(a.t, list, subset, msgAndArgs...)
 }
 
-// Subsetf asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subsetf asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
+//	a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted")
+//	a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
 func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
diff --git a/assert/assertions.go b/assert/assertions.go
index 1e55fbf..909daa5 100644
--- a/assert/assertions.go
+++ b/assert/assertions.go
@@ -150,6 +150,8 @@ func copyExportedFields(expected interface{}) interface{} {
 // structures.
 //
 // This function does no assertion of any kind.
+//
+// Deprecated: Use [EqualExportedValues] instead.
 func ObjectsExportedFieldsAreEqual(expected, actual interface{}) bool {
 	expectedCleaned := copyExportedFields(expected)
 	actualCleaned := copyExportedFields(actual)
@@ -630,17 +632,6 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
 	return Fail(t, "Expected value not to be nil.", msgAndArgs...)
 }
 
-// containsKind checks if a specified kind in the slice of kinds.
-func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool {
-	for i := 0; i < len(kinds); i++ {
-		if kind == kinds[i] {
-			return true
-		}
-	}
-
-	return false
-}
-
 // isNil checks if a specified object is nil or not, without Failing.
 func isNil(object interface{}) bool {
 	if object == nil {
@@ -648,16 +639,13 @@ func isNil(object interface{}) bool {
 	}
 
 	value := reflect.ValueOf(object)
-	kind := value.Kind()
-	isNilableKind := containsKind(
-		[]reflect.Kind{
-			reflect.Chan, reflect.Func,
-			reflect.Interface, reflect.Map,
-			reflect.Ptr, reflect.Slice, reflect.UnsafePointer},
-		kind)
+	switch value.Kind() {
+	case
+		reflect.Chan, reflect.Func,
+		reflect.Interface, reflect.Map,
+		reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
 
-	if isNilableKind && value.IsNil() {
-		return true
+		return value.IsNil()
 	}
 
 	return false
@@ -927,10 +915,11 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
 
 }
 
-// Subset asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subset asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
+//	assert.Subset(t, [1, 2, 3], [1, 2])
+//	assert.Subset(t, {"x": 1, "y": 2}, {"x": 1})
 func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -983,10 +972,12 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
 	return true
 }
 
-// NotSubset asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubset asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
+//	assert.NotSubset(t, [1, 3, 4], [1, 2])
+//	assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3})
 func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -1466,19 +1457,26 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
-	if expected == nil || actual == nil ||
-		reflect.TypeOf(actual).Kind() != reflect.Slice ||
-		reflect.TypeOf(expected).Kind() != reflect.Slice {
+
+	if expected == nil || actual == nil {
 		return Fail(t, "Parameters must be slice", msgAndArgs...)
 	}
 
-	actualSlice := reflect.ValueOf(actual)
 	expectedSlice := reflect.ValueOf(expected)
+	actualSlice := reflect.ValueOf(actual)
 
-	for i := 0; i < actualSlice.Len(); i++ {
-		result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon)
-		if !result {
-			return result
+	if expectedSlice.Type().Kind() != reflect.Slice {
+		return Fail(t, "Expected value must be slice", msgAndArgs...)
+	}
+
+	expectedLen := expectedSlice.Len()
+	if !IsType(t, expected, actual) || !Len(t, actual, expectedLen) {
+		return false
+	}
+
+	for i := 0; i < expectedLen; i++ {
+		if !InEpsilon(t, expectedSlice.Index(i).Interface(), actualSlice.Index(i).Interface(), epsilon, "at index %d", i) {
+			return false
 		}
 	}
 
diff --git a/assert/assertions_test.go b/assert/assertions_test.go
index 75ee795..d65dd02 100644
--- a/assert/assertions_test.go
+++ b/assert/assertions_test.go
@@ -16,7 +16,6 @@ import (
 	"strings"
 	"testing"
 	"time"
-	"unsafe"
 )
 
 var (
@@ -2922,52 +2921,211 @@ func Test_truncatingFormat(t *testing.T) {
 	}
 }
 
+// parseLabeledOutput does the inverse of labeledOutput - it takes a formatted
+// output string and turns it back into a slice of labeledContent.
+func parseLabeledOutput(output string) []labeledContent {
+	labelPattern := regexp.MustCompile(`^\t([^\t]*): *\t(.*)$`)
+	contentPattern := regexp.MustCompile(`^\t *\t(.*)$`)
+	var contents []labeledContent
+	lines := strings.Split(output, "\n")
+	i := -1
+	for _, line := range lines {
+		if line == "" {
+			// skip blank lines
+			continue
+		}
+		matches := labelPattern.FindStringSubmatch(line)
+		if len(matches) == 3 {
+			// a label
+			contents = append(contents, labeledContent{
+				label:   matches[1],
+				content: matches[2] + "\n",
+			})
+			i++
+			continue
+		}
+		matches = contentPattern.FindStringSubmatch(line)
+		if len(matches) == 2 {
+			// just content
+			if i >= 0 {
+				contents[i].content += matches[1] + "\n"
+				continue
+			}
+		}
+		// Couldn't parse output
+		return nil
+	}
+	return contents
+}
+
+type captureTestingT struct {
+	msg string
+}
+
+func (ctt *captureTestingT) Errorf(format string, args ...interface{}) {
+	ctt.msg = fmt.Sprintf(format, args...)
+}
+
+func (ctt *captureTestingT) checkResultAndErrMsg(t *testing.T, expectedRes, res bool, expectedErrMsg string) {
+	t.Helper()
+	if res != expectedRes {
+		t.Errorf("Should return %t", expectedRes)
+		return
+	}
+	contents := parseLabeledOutput(ctt.msg)
+	if res == true {
+		if contents != nil {
+			t.Errorf("Should not log an error")
+		}
+		return
+	}
+	if contents == nil {
+		t.Errorf("Should log an error. Log output: %v", ctt.msg)
+		return
+	}
+	for _, content := range contents {
+		if content.label == "Error" {
+			if expectedErrMsg == content.content {
+				return
+			}
+			t.Errorf("Logged Error: %v", content.content)
+		}
+	}
+	t.Errorf("Should log Error: %v", expectedErrMsg)
+}
+
 func TestErrorIs(t *testing.T) {
-	mockT := new(testing.T)
 	tests := []struct {
-		err    error
-		target error
-		result bool
+		err          error
+		target       error
+		result       bool
+		resultErrMsg string
 	}{
-		{io.EOF, io.EOF, true},
-		{fmt.Errorf("wrap: %w", io.EOF), io.EOF, true},
-		{io.EOF, io.ErrClosedPipe, false},
-		{nil, io.EOF, false},
-		{io.EOF, nil, false},
-		{nil, nil, true},
+		{
+			err:    io.EOF,
+			target: io.EOF,
+			result: true,
+		},
+		{
+			err:    fmt.Errorf("wrap: %w", io.EOF),
+			target: io.EOF,
+			result: true,
+		},
+		{
+			err:    io.EOF,
+			target: io.ErrClosedPipe,
+			result: false,
+			resultErrMsg: "" +
+				"Target error should be in err chain:\n" +
+				"expected: \"io: read/write on closed pipe\"\n" +
+				"in chain: \"EOF\"\n",
+		},
+		{
+			err:    nil,
+			target: io.EOF,
+			result: false,
+			resultErrMsg: "" +
+				"Target error should be in err chain:\n" +
+				"expected: \"EOF\"\n" +
+				"in chain: \n",
+		},
+		{
+			err:    io.EOF,
+			target: nil,
+			result: false,
+			resultErrMsg: "" +
+				"Target error should be in err chain:\n" +
+				"expected: \"\"\n" +
+				"in chain: \"EOF\"\n",
+		},
+		{
+			err:    nil,
+			target: nil,
+			result: true,
+		},
+		{
+			err:    fmt.Errorf("abc: %w", errors.New("def")),
+			target: io.EOF,
+			result: false,
+			resultErrMsg: "" +
+				"Target error should be in err chain:\n" +
+				"expected: \"EOF\"\n" +
+				"in chain: \"abc: def\"\n" +
+				"\t\"def\"\n",
+		},
 	}
 	for _, tt := range tests {
 		tt := tt
 		t.Run(fmt.Sprintf("ErrorIs(%#v,%#v)", tt.err, tt.target), func(t *testing.T) {
+			mockT := new(captureTestingT)
 			res := ErrorIs(mockT, tt.err, tt.target)
-			if res != tt.result {
-				t.Errorf("ErrorIs(%#v,%#v) should return %t", tt.err, tt.target, tt.result)
-			}
+			mockT.checkResultAndErrMsg(t, tt.result, res, tt.resultErrMsg)
 		})
 	}
 }
 
 func TestNotErrorIs(t *testing.T) {
-	mockT := new(testing.T)
 	tests := []struct {
-		err    error
-		target error
-		result bool
+		err          error
+		target       error
+		result       bool
+		resultErrMsg string
 	}{
-		{io.EOF, io.EOF, false},
-		{fmt.Errorf("wrap: %w", io.EOF), io.EOF, false},
-		{io.EOF, io.ErrClosedPipe, true},
-		{nil, io.EOF, true},
-		{io.EOF, nil, true},
-		{nil, nil, false},
+		{
+			err:    io.EOF,
+			target: io.EOF,
+			result: false,
+			resultErrMsg: "" +
+				"Target error should not be in err chain:\n" +
+				"found: \"EOF\"\n" +
+				"in chain: \"EOF\"\n",
+		},
+		{
+			err:    fmt.Errorf("wrap: %w", io.EOF),
+			target: io.EOF,
+			result: false,
+			resultErrMsg: "" +
+				"Target error should not be in err chain:\n" +
+				"found: \"EOF\"\n" +
+				"in chain: \"wrap: EOF\"\n" +
+				"\t\"EOF\"\n",
+		},
+		{
+			err:    io.EOF,
+			target: io.ErrClosedPipe,
+			result: true,
+		},
+		{
+			err:    nil,
+			target: io.EOF,
+			result: true,
+		},
+		{
+			err:    io.EOF,
+			target: nil,
+			result: true,
+		},
+		{
+			err:    nil,
+			target: nil,
+			result: false,
+			resultErrMsg: "" +
+				"Target error should not be in err chain:\n" +
+				"found: \"\"\n" +
+				"in chain: \n",
+		},
+		{
+			err:    fmt.Errorf("abc: %w", errors.New("def")),
+			target: io.EOF,
+			result: true,
+		},
 	}
 	for _, tt := range tests {
 		tt := tt
 		t.Run(fmt.Sprintf("NotErrorIs(%#v,%#v)", tt.err, tt.target), func(t *testing.T) {
+			mockT := new(captureTestingT)
 			res := NotErrorIs(mockT, tt.err, tt.target)
-			if res != tt.result {
-				t.Errorf("NotErrorIs(%#v,%#v) should return %t", tt.err, tt.target, tt.result)
-			}
+			mockT.checkResultAndErrMsg(t, tt.result, res, tt.resultErrMsg)
 		})
 	}
 }
@@ -2993,10 +3151,3 @@ func TestErrorAs(t *testing.T) {
 		})
 	}
 }
-
-func TestIsNil(t *testing.T) {
-	var n unsafe.Pointer = nil
-	if !isNil(n) {
-		t.Fatal("fail")
-	}
-}
diff --git a/assert/internal/unsafetests/doc.go b/assert/internal/unsafetests/doc.go
new file mode 100644
index 0000000..08172d5
--- /dev/null
+++ b/assert/internal/unsafetests/doc.go
@@ -0,0 +1,4 @@
+// This package exists just to isolate tests that reference the [unsafe] package.
+//
+// The tests in this package are totally safe.
+package unsafetests
diff --git a/assert/internal/unsafetests/unsafetests_test.go b/assert/internal/unsafetests/unsafetests_test.go
new file mode 100644
index 0000000..b7f01a6
--- /dev/null
+++ b/assert/internal/unsafetests/unsafetests_test.go
@@ -0,0 +1,34 @@
+package unsafetests_test
+
+import (
+	"fmt"
+	"testing"
+	"unsafe"
+
+	"github.com/stretchr/testify/assert"
+)
+
+type ignoreTestingT struct{}
+
+var _ assert.TestingT = ignoreTestingT{}
+
+func (ignoreTestingT) Helper() {}
+
+func (ignoreTestingT) Errorf(format string, args ...interface{}) {
+	// Run the formatting, but ignore the result
+	msg := fmt.Sprintf(format, args...)
+	_ = msg
+}
+
+func TestUnsafePointers(t *testing.T) {
+	var ignore ignoreTestingT
+
+	assert.True(t, assert.Nil(t, unsafe.Pointer(nil), "unsafe.Pointer(nil) is nil"))
+	assert.False(t, assert.NotNil(ignore, unsafe.Pointer(nil), "unsafe.Pointer(nil) is nil"))
+
+	assert.True(t, assert.Nil(t, unsafe.Pointer((*int)(nil)), "unsafe.Pointer((*int)(nil)) is nil"))
+	assert.False(t, assert.NotNil(ignore, unsafe.Pointer((*int)(nil)), "unsafe.Pointer((*int)(nil)) is nil"))
+
+	assert.False(t, assert.Nil(ignore, unsafe.Pointer(new(int)), "unsafe.Pointer(new(int)) is NOT nil"))
+	assert.True(t, assert.NotNil(t, unsafe.Pointer(new(int)), "unsafe.Pointer(new(int)) is NOT nil"))
+}
diff --git a/doc.go b/doc.go
index 3460b46..aac5ef3 100644
--- a/doc.go
+++ b/doc.go
@@ -5,19 +5,7 @@
 //
 // The assert package provides a comprehensive set of assertion functions that tie in to the Go testing system.
 //
-// The http package contains tools to make it easier to test http activity using the Go testing system.
-//
 // The mock package provides a system by which it is possible to mock your objects and verify calls are happening as expected.
 //
 // The suite package provides a basic structure for using structs as testing suites, and methods on those structs as tests.  It includes setup/teardown functionality in the way of interfaces.
 package testify
-
-// blank imports help docs.
-import (
-	// assert package
-	_ "github.com/stretchr/testify/assert"
-	// http package
-	_ "github.com/stretchr/testify/http"
-	// mock package
-	_ "github.com/stretchr/testify/mock"
-)
diff --git a/go.mod b/go.mod
index d3c4d72..9133c4a 100644
--- a/go.mod
+++ b/go.mod
@@ -7,6 +7,10 @@ go 1.17
 require (
 	github.com/davecgh/go-spew v1.1.1
 	github.com/pmezard/go-difflib v1.0.0
-	github.com/stretchr/objx v0.5.0
+	github.com/stretchr/objx v0.5.1
 	gopkg.in/yaml.v3 v3.0.1
 )
+
+// Break dependency cycle with objx.
+// See https://github.com/stretchr/objx/pull/140
+exclude github.com/stretchr/testify v1.8.2
diff --git a/go.sum b/go.sum
index 4f3ced6..f218355 100644
--- a/go.sum
+++ b/go.sum
@@ -1,16 +1,10 @@
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
-github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
-github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0=
+github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/http/doc.go b/http/doc.go
index 695167c..7c800aa 100644
--- a/http/doc.go
+++ b/http/doc.go
@@ -1,2 +1,2 @@
-// Package http DEPRECATED USE net/http/httptest
+// Deprecated: Use [net/http/httptest] instead.
 package http
diff --git a/http/test_response_writer.go b/http/test_response_writer.go
index 300a63b..6744e1c 100644
--- a/http/test_response_writer.go
+++ b/http/test_response_writer.go
@@ -4,7 +4,7 @@ import (
 	"net/http"
 )
 
-// TestResponseWriter DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
+// Deprecated: Use [net/http/httptest] instead.
 type TestResponseWriter struct {
 
 	// StatusCode is the last int written by the call to WriteHeader(int)
@@ -17,7 +17,7 @@ type TestResponseWriter struct {
 	header http.Header
 }
 
-// Header DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
+// Deprecated: Use [net/http/httptest] instead.
 func (rw *TestResponseWriter) Header() http.Header {
 
 	if rw.header == nil {
@@ -27,7 +27,7 @@ func (rw *TestResponseWriter) Header() http.Header {
 	return rw.header
 }
 
-// Write DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
+// Deprecated: Use [net/http/httptest] instead.
 func (rw *TestResponseWriter) Write(bytes []byte) (int, error) {
 
 	// assume 200 success if no header has been set
@@ -43,7 +43,7 @@ func (rw *TestResponseWriter) Write(bytes []byte) (int, error) {
 
 }
 
-// WriteHeader DEPRECATED: We recommend you use http://golang.org/pkg/net/http/httptest instead.
+// Deprecated: Use [net/http/httptest] instead.
 func (rw *TestResponseWriter) WriteHeader(i int) {
 	rw.StatusCode = i
 }
diff --git a/http/test_round_tripper.go b/http/test_round_tripper.go
index 11a024e..a0bdd71 100644
--- a/http/test_round_tripper.go
+++ b/http/test_round_tripper.go
@@ -6,12 +6,12 @@ import (
 	"github.com/stretchr/testify/mock"
 )
 
-// TestRoundTripper DEPRECATED USE net/http/httptest
+// Deprecated: Use [net/http/httptest] instead.
 type TestRoundTripper struct {
 	mock.Mock
 }
 
-// RoundTrip DEPRECATED USE net/http/httptest
+// Deprecated: Use [net/http/httptest] instead.
 func (t *TestRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
 	args := t.Called(req)
 	return args.Get(0).(*http.Response), args.Error(1)
diff --git a/mock/mock.go b/mock/mock.go
index 3234436..5e35861 100644
--- a/mock/mock.go
+++ b/mock/mock.go
@@ -786,7 +786,7 @@ func AnythingOfType(t string) AnythingOfTypeArgument {
 // for use when type checking.  This is an alternative to AnythingOfType.
 // Used in Diff and Assert.
 type IsTypeArgument struct {
-	t interface{}
+	t reflect.Type
 }
 
 // IsType returns an IsTypeArgument object containing the type to check for.
@@ -796,7 +796,7 @@ type IsTypeArgument struct {
 // For example:
 // Assert(t, IsType(""), IsType(0))
 func IsType(t interface{}) *IsTypeArgument {
-	return &IsTypeArgument{t: t}
+	return &IsTypeArgument{t: reflect.TypeOf(t)}
 }
 
 // FunctionalOptionsArgument is a struct that contains the type and value of an functional option argument
@@ -960,53 +960,55 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
 				differences++
 				output = fmt.Sprintf("%s\t%d: FAIL:  %s not matched by %s\n", output, i, actualFmt, matcher)
 			}
-		} else if reflect.TypeOf(expected) == reflect.TypeOf((*anythingOfTypeArgument)(nil)).Elem() {
-			// type checking
-			if reflect.TypeOf(actual).Name() != string(expected.(anythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(anythingOfTypeArgument)) {
-				// not match
-				differences++
-				output = fmt.Sprintf("%s\t%d: FAIL:  type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt)
-			}
-		} else if reflect.TypeOf(expected) == reflect.TypeOf((*IsTypeArgument)(nil)) {
-			t := expected.(*IsTypeArgument).t
-			if reflect.TypeOf(t) != reflect.TypeOf(actual) {
-				differences++
-				output = fmt.Sprintf("%s\t%d: FAIL:  type %s != type %s - %s\n", output, i, reflect.TypeOf(t).Name(), reflect.TypeOf(actual).Name(), actualFmt)
-			}
-		} else if reflect.TypeOf(expected) == reflect.TypeOf((*FunctionalOptionsArgument)(nil)) {
-			t := expected.(*FunctionalOptionsArgument).value
+		} else {
+			switch expected := expected.(type) {
+			case anythingOfTypeArgument:
+				// type checking
+				if reflect.TypeOf(actual).Name() != string(expected) && reflect.TypeOf(actual).String() != string(expected) {
+					// not match
+					differences++
+					output = fmt.Sprintf("%s\t%d: FAIL:  type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actualFmt)
+				}
+			case *IsTypeArgument:
+				actualT := reflect.TypeOf(actual)
+				if actualT != expected.t {
+					differences++
+					output = fmt.Sprintf("%s\t%d: FAIL:  type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt)
+				}
+			case *FunctionalOptionsArgument:
+				t := expected.value
 
-			var name string
-			tValue := reflect.ValueOf(t)
-			if tValue.Len() > 0 {
-				name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String()
-			}
+				var name string
+				tValue := reflect.ValueOf(t)
+				if tValue.Len() > 0 {
+					name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String()
+				}
 
-			tName := reflect.TypeOf(t).Name()
-			if name != reflect.TypeOf(actual).String() && tValue.Len() != 0 {
-				differences++
-				output = fmt.Sprintf("%s\t%d: FAIL:  type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt)
-			} else {
-				if ef, af := assertOpts(t, actual); ef == "" && af == "" {
+				tName := reflect.TypeOf(t).Name()
+				if name != reflect.TypeOf(actual).String() && tValue.Len() != 0 {
+					differences++
+					output = fmt.Sprintf("%s\t%d: FAIL:  type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt)
+				} else {
+					if ef, af := assertOpts(t, actual); ef == "" && af == "" {
+						// match
+						output = fmt.Sprintf("%s\t%d: PASS:  %s == %s\n", output, i, tName, tName)
+					} else {
+						// not match
+						differences++
+						output = fmt.Sprintf("%s\t%d: FAIL:  %s != %s\n", output, i, af, ef)
+					}
+				}
+
+			default:
+				if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
 					// match
-					output = fmt.Sprintf("%s\t%d: PASS:  %s == %s\n", output, i, tName, tName)
+					output = fmt.Sprintf("%s\t%d: PASS:  %s == %s\n", output, i, actualFmt, expectedFmt)
 				} else {
 					// not match
 					differences++
-					output = fmt.Sprintf("%s\t%d: FAIL:  %s != %s\n", output, i, af, ef)
+					output = fmt.Sprintf("%s\t%d: FAIL:  %s != %s\n", output, i, actualFmt, expectedFmt)
 				}
 			}
-		} else {
-			// normal checking
-
-			if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
-				// match
-				output = fmt.Sprintf("%s\t%d: PASS:  %s == %s\n", output, i, actualFmt, expectedFmt)
-			} else {
-				// not match
-				differences++
-				output = fmt.Sprintf("%s\t%d: FAIL:  %s != %s\n", output, i, actualFmt, expectedFmt)
-			}
 		}
 
 	}
diff --git a/mock/mock_test.go b/mock/mock_test.go
index 77493c5..52d20be 100644
--- a/mock/mock_test.go
+++ b/mock/mock_test.go
@@ -1616,17 +1616,14 @@ func Test_Mock_IsMethodCallable(t *testing.T) {
 
 func TestIsArgsEqual(t *testing.T) {
 	var expected = Arguments{5, 3, 4, 6, 7, 2}
-	var args = make([]interface{}, 5)
-	for i := 1; i < len(expected); i++ {
-		args[i-1] = expected[i]
-	}
+
+	// Copy elements 1 to 5
+	args := append(([]interface{})(nil), expected[1:]...)
 	args[2] = expected[1]
 	assert.False(t, isArgsEqual(expected, args))
 
-	var arr = make([]interface{}, 6)
-	for i := 0; i < len(expected); i++ {
-		arr[i] = expected[i]
-	}
+	// Clone
+	arr := append(([]interface{})(nil), expected...)
 	assert.True(t, isArgsEqual(expected, arr))
 }
 
diff --git a/require/require.go b/require/require.go
index fa3792b..fde0833 100644
--- a/require/require.go
+++ b/require/require.go
@@ -1655,10 +1655,12 @@ func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string,
 	t.FailNow()
 }
 
-// NotSubset asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubset asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
+//	assert.NotSubset(t, [1, 3, 4], [1, 2])
+//	assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3})
 func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -1669,10 +1671,12 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i
 	t.FailNow()
 }
 
-// NotSubsetf asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
+//	assert.NotSubsetf(t, [1, 3, 4], [1, 2], "error message %s", "formatted")
+//	assert.NotSubsetf(t, {"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
 func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -1877,10 +1881,11 @@ func Samef(t TestingT, expected interface{}, actual interface{}, msg string, arg
 	t.FailNow()
 }
 
-// Subset asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subset asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
+//	assert.Subset(t, [1, 2, 3], [1, 2])
+//	assert.Subset(t, {"x": 1, "y": 2}, {"x": 1})
 func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
@@ -1891,10 +1896,11 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte
 	t.FailNow()
 }
 
-// Subsetf asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subsetf asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
+//	assert.Subsetf(t, [1, 2, 3], [1, 2], "error message %s", "formatted")
+//	assert.Subsetf(t, {"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
 func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
diff --git a/require/require_forward.go b/require/require_forward.go
index 99e19ea..8fddd1f 100644
--- a/require/require_forward.go
+++ b/require/require_forward.go
@@ -1307,10 +1307,12 @@ func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg stri
 	NotSamef(a.t, expected, actual, msg, args...)
 }
 
-// NotSubset asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubset asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
+//	a.NotSubset([1, 3, 4], [1, 2])
+//	a.NotSubset({"x": 1, "y": 2}, {"z": 3})
 func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1318,10 +1320,12 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
 	NotSubset(a.t, list, subset, msgAndArgs...)
 }
 
-// NotSubsetf asserts that the specified list(array, slice...) contains not all
-// elements given in the specified subset(array, slice...).
+// NotSubsetf asserts that the specified list(array, slice...) or map does NOT
+// contain all elements given in the specified subset list(array, slice...) or
+// map.
 //
-//	a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
+//	a.NotSubsetf([1, 3, 4], [1, 2], "error message %s", "formatted")
+//	a.NotSubsetf({"x": 1, "y": 2}, {"z": 3}, "error message %s", "formatted")
 func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1481,10 +1485,11 @@ func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string,
 	Samef(a.t, expected, actual, msg, args...)
 }
 
-// Subset asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subset asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
+//	a.Subset([1, 2, 3], [1, 2])
+//	a.Subset({"x": 1, "y": 2}, {"x": 1})
 func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
@@ -1492,10 +1497,11 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
 	Subset(a.t, list, subset, msgAndArgs...)
 }
 
-// Subsetf asserts that the specified list(array, slice...) contains all
-// elements given in the specified subset(array, slice...).
+// Subsetf asserts that the specified list(array, slice...) or map contains all
+// elements given in the specified subset list(array, slice...) or map.
 //
-//	a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
+//	a.Subsetf([1, 2, 3], [1, 2], "error message %s", "formatted")
+//	a.Subsetf({"x": 1, "y": 2}, {"x": 1}, "error message %s", "formatted")
 func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {
 	if h, ok := a.t.(tHelper); ok {
 		h.Helper()
diff --git a/suite/suite.go b/suite/suite.go
index 8b4202d..f3aa9a1 100644
--- a/suite/suite.go
+++ b/suite/suite.go
@@ -96,19 +96,20 @@ func failOnPanic(t *testing.T, r interface{}) {
 func (suite *Suite) Run(name string, subtest func()) bool {
 	oldT := suite.T()
 
-	if setupSubTest, ok := suite.s.(SetupSubTest); ok {
-		setupSubTest.SetupSubTest()
-	}
-
-	defer func() {
-		suite.SetT(oldT)
-		if tearDownSubTest, ok := suite.s.(TearDownSubTest); ok {
-			tearDownSubTest.TearDownSubTest()
-		}
-	}()
-
 	return oldT.Run(name, func(t *testing.T) {
 		suite.SetT(t)
+		defer suite.SetT(oldT)
+
+		defer recoverAndFailOnPanic(t)
+
+		if setupSubTest, ok := suite.s.(SetupSubTest); ok {
+			setupSubTest.SetupSubTest()
+		}
+
+		if tearDownSubTest, ok := suite.s.(TearDownSubTest); ok {
+			defer tearDownSubTest.TearDownSubTest()
+		}
+
 		subtest()
 	})
 }
diff --git a/suite/suite_test.go b/suite/suite_test.go
index d684f52..292dc29 100644
--- a/suite/suite_test.go
+++ b/suite/suite_test.go
@@ -27,14 +27,14 @@ func TestSuiteRequireTwice(t *testing.T) {
 	ok := testing.RunTests(
 		allTestsFilter,
 		[]testing.InternalTest{{
-			Name: "TestSuiteRequireTwice",
+			Name: t.Name() + "/SuiteRequireTwice",
 			F: func(t *testing.T) {
 				suite := new(SuiteRequireTwice)
 				Run(t, suite)
 			},
 		}},
 	)
-	assert.Equal(t, false, ok)
+	assert.False(t, ok)
 }
 
 func (s *SuiteRequireTwice) TestRequireOne() {
@@ -104,31 +104,31 @@ func TestSuiteRecoverPanic(t *testing.T) {
 	ok := true
 	panickingTests := []testing.InternalTest{
 		{
-			Name: "TestPanicInSetupSuite",
+			Name: t.Name() + "/InSetupSuite",
 			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupSuite: true}) },
 		},
 		{
-			Name: "TestPanicInSetupTest",
+			Name: t.Name() + "/InSetupTest",
 			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupTest: true}) },
 		},
 		{
-			Name: "TestPanicInBeforeTest",
+			Name: t.Name() + "InBeforeTest",
 			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInBeforeTest: true}) },
 		},
 		{
-			Name: "TestPanicInTest",
+			Name: t.Name() + "/InTest",
 			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTest: true}) },
 		},
 		{
-			Name: "TestPanicInAfterTest",
+			Name: t.Name() + "/InAfterTest",
 			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInAfterTest: true}) },
 		},
 		{
-			Name: "TestPanicInTearDownTest",
+			Name: t.Name() + "/InTearDownTest",
 			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownTest: true}) },
 		},
 		{
-			Name: "TestPanicInTearDownSuite",
+			Name: t.Name() + "/InTearDownSuite",
 			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownSuite: true}) },
 		},
 	}
@@ -162,6 +162,9 @@ type SuiteTester struct {
 	SetupSubTestRunCount    int
 	TearDownSubTestRunCount int
 
+	SetupSubTestNames    []string
+	TearDownSubTestNames []string
+
 	SuiteNameBefore []string
 	TestNameBefore  []string
 
@@ -258,10 +261,12 @@ func (suite *SuiteTester) TestSubtest() {
 }
 
 func (suite *SuiteTester) TearDownSubTest() {
+	suite.TearDownSubTestNames = append(suite.TearDownSubTestNames, suite.T().Name())
 	suite.TearDownSubTestRunCount++
 }
 
 func (suite *SuiteTester) SetupSubTest() {
+	suite.SetupSubTestNames = append(suite.SetupSubTestNames, suite.T().Name())
 	suite.SetupSubTestRunCount++
 }
 
@@ -301,13 +306,13 @@ func TestRunSuite(t *testing.T) {
 
 	// The suite was only run once, so the SetupSuite and TearDownSuite
 	// methods should have each been run only once.
-	assert.Equal(t, suiteTester.SetupSuiteRunCount, 1)
-	assert.Equal(t, suiteTester.TearDownSuiteRunCount, 1)
+	assert.Equal(t, 1, suiteTester.SetupSuiteRunCount)
+	assert.Equal(t, 1, suiteTester.TearDownSuiteRunCount)
 
-	assert.Equal(t, len(suiteTester.SuiteNameAfter), 4)
-	assert.Equal(t, len(suiteTester.SuiteNameBefore), 4)
-	assert.Equal(t, len(suiteTester.TestNameAfter), 4)
-	assert.Equal(t, len(suiteTester.TestNameBefore), 4)
+	assert.Len(t, suiteTester.SuiteNameAfter, 4)
+	assert.Len(t, suiteTester.SuiteNameBefore, 4)
+	assert.Len(t, suiteTester.TestNameAfter, 4)
+	assert.Len(t, suiteTester.TestNameBefore, 4)
 
 	assert.Contains(t, suiteTester.TestNameAfter, "TestOne")
 	assert.Contains(t, suiteTester.TestNameAfter, "TestTwo")
@@ -319,6 +324,12 @@ func TestRunSuite(t *testing.T) {
 	assert.Contains(t, suiteTester.TestNameBefore, "TestSkip")
 	assert.Contains(t, suiteTester.TestNameBefore, "TestSubtest")
 
+	assert.Contains(t, suiteTester.SetupSubTestNames, "TestRunSuite/TestSubtest/first")
+	assert.Contains(t, suiteTester.SetupSubTestNames, "TestRunSuite/TestSubtest/second")
+
+	assert.Contains(t, suiteTester.TearDownSubTestNames, "TestRunSuite/TestSubtest/first")
+	assert.Contains(t, suiteTester.TearDownSubTestNames, "TestRunSuite/TestSubtest/second")
+
 	for _, suiteName := range suiteTester.SuiteNameAfter {
 		assert.Equal(t, "SuiteTester", suiteName)
 	}
@@ -338,20 +349,20 @@ func TestRunSuite(t *testing.T) {
 	// There are four test methods (TestOne, TestTwo, TestSkip, and TestSubtest), so
 	// the SetupTest and TearDownTest methods (which should be run once for
 	// each test) should have been run four times.
-	assert.Equal(t, suiteTester.SetupTestRunCount, 4)
-	assert.Equal(t, suiteTester.TearDownTestRunCount, 4)
+	assert.Equal(t, 4, suiteTester.SetupTestRunCount)
+	assert.Equal(t, 4, suiteTester.TearDownTestRunCount)
 
 	// Each test should have been run once.
-	assert.Equal(t, suiteTester.TestOneRunCount, 1)
-	assert.Equal(t, suiteTester.TestTwoRunCount, 1)
-	assert.Equal(t, suiteTester.TestSubtestRunCount, 1)
+	assert.Equal(t, 1, suiteTester.TestOneRunCount)
+	assert.Equal(t, 1, suiteTester.TestTwoRunCount)
+	assert.Equal(t, 1, suiteTester.TestSubtestRunCount)
 
-	assert.Equal(t, suiteTester.TearDownSubTestRunCount, 2)
-	assert.Equal(t, suiteTester.SetupSubTestRunCount, 2)
+	assert.Equal(t, 2, suiteTester.TearDownSubTestRunCount)
+	assert.Equal(t, 2, suiteTester.SetupSubTestRunCount)
 
 	// Methods that don't match the test method identifier shouldn't
 	// have been run at all.
-	assert.Equal(t, suiteTester.NonTestMethodRunCount, 0)
+	assert.Equal(t, 0, suiteTester.NonTestMethodRunCount)
 
 	suiteSkipTester := new(SuiteSkipTester)
 	Run(t, suiteSkipTester)
@@ -359,8 +370,8 @@ func TestRunSuite(t *testing.T) {
 	// The suite was only run once, so the SetupSuite and TearDownSuite
 	// methods should have each been run only once, even though SetupSuite
 	// called Skip()
-	assert.Equal(t, suiteSkipTester.SetupSuiteRunCount, 1)
-	assert.Equal(t, suiteSkipTester.TearDownSuiteRunCount, 1)
+	assert.Equal(t, 1, suiteSkipTester.SetupSuiteRunCount)
+	assert.Equal(t, 1, suiteSkipTester.TearDownSuiteRunCount)
 
 }
 
@@ -440,7 +451,7 @@ func TestSuiteLogging(t *testing.T) {
 	suiteLoggingTester := new(SuiteLoggingTester)
 	capture := StdoutCapture{}
 	internalTest := testing.InternalTest{
-		Name: "SomeTest",
+		Name: t.Name() + "/SuiteLoggingTester",
 		F: func(subT *testing.T) {
 			Run(subT, suiteLoggingTester)
 		},
@@ -481,7 +492,7 @@ func (s *CallOrderSuite) SetupSuite() {
 
 func (s *CallOrderSuite) TearDownSuite() {
 	s.call("TearDownSuite")
-	assert.Equal(s.T(), "SetupSuite;SetupTest;Test A;TearDownTest;SetupTest;Test B;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";"))
+	assert.Equal(s.T(), "SetupSuite;SetupTest;Test A;SetupSubTest;SubTest A1;TearDownSubTest;SetupSubTest;SubTest A2;TearDownSubTest;TearDownTest;SetupTest;Test B;SetupSubTest;SubTest B1;TearDownSubTest;SetupSubTest;SubTest B2;TearDownSubTest;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";"))
 }
 func (s *CallOrderSuite) SetupTest() {
 	s.call("SetupTest")
@@ -491,12 +502,32 @@ func (s *CallOrderSuite) TearDownTest() {
 	s.call("TearDownTest")
 }
 
+func (s *CallOrderSuite) SetupSubTest() {
+	s.call("SetupSubTest")
+}
+
+func (s *CallOrderSuite) TearDownSubTest() {
+	s.call("TearDownSubTest")
+}
+
 func (s *CallOrderSuite) Test_A() {
 	s.call("Test A")
+	s.Run("SubTest A1", func() {
+		s.call("SubTest A1")
+	})
+	s.Run("SubTest A2", func() {
+		s.call("SubTest A2")
+	})
 }
 
 func (s *CallOrderSuite) Test_B() {
 	s.call("Test B")
+	s.Run("SubTest B1", func() {
+		s.call("SubTest B1")
+	})
+	s.Run("SubTest B2", func() {
+		s.call("SubTest B2")
+	})
 }
 
 type suiteWithStats struct {
@@ -521,14 +552,15 @@ func (s *suiteWithStats) TestPanic() {
 func TestSuiteWithStats(t *testing.T) {
 	suiteWithStats := new(suiteWithStats)
 
-	testing.RunTests(allTestsFilter, []testing.InternalTest{
+	suiteSuccess := testing.RunTests(allTestsFilter, []testing.InternalTest{
 		{
-			Name: "WithStats",
+			Name: t.Name() + "/suiteWithStats",
 			F: func(t *testing.T) {
 				Run(t, suiteWithStats)
 			},
 		},
 	})
+	require.False(t, suiteSuccess, "suiteWithStats should report test failure because of panic in TestPanic")
 
 	assert.True(t, suiteWithStats.wasCalled)
 	assert.NotZero(t, suiteWithStats.stats.Start)
@@ -565,13 +597,13 @@ func TestFailfastSuite(t *testing.T) {
 	ok := testing.RunTests(
 		allTestsFilter,
 		[]testing.InternalTest{{
-			Name: "TestFailfastSuite",
+			Name: t.Name() + "/FailfastSuite",
 			F: func(t *testing.T) {
 				Run(t, s)
 			},
 		}},
 	)
-	assert.Equal(t, false, ok)
+	assert.False(t, ok)
 	if failFast {
 		// Test A Fails and because we are running with failfast Test B never runs and we proceed straight to TearDownSuite
 		assert.Equal(t, "SetupSuite;SetupTest;Test A Fails;TearDownTest;TearDownSuite", strings.Join(s.callOrder, ";"))
@@ -617,3 +649,46 @@ func (s *FailfastSuite) Test_B_Passes() {
 	s.call("Test B Passes")
 	s.Require().True(true)
 }
+
+type subtestPanicSuite struct {
+	Suite
+	inTearDownSuite   bool
+	inTearDownTest    bool
+	inTearDownSubTest bool
+}
+
+func (s *subtestPanicSuite) TearDownSuite() {
+	s.inTearDownSuite = true
+}
+
+func (s *subtestPanicSuite) TearDownTest() {
+	s.inTearDownTest = true
+}
+
+func (s *subtestPanicSuite) TearDownSubTest() {
+	s.inTearDownSubTest = true
+}
+
+func (s *subtestPanicSuite) TestSubtestPanic() {
+	ok := s.Run("subtest", func() {
+		panic("panic")
+	})
+	s.False(ok, "subtest failure is expected")
+}
+
+func TestSubtestPanic(t *testing.T) {
+	suite := new(subtestPanicSuite)
+	ok := testing.RunTests(
+		allTestsFilter,
+		[]testing.InternalTest{{
+			Name: t.Name() + "/subtestPanicSuite",
+			F: func(t *testing.T) {
+				Run(t, suite)
+			},
+		}},
+	)
+	assert.False(t, ok, "TestSubtestPanic/subtest should make the testsuite fail")
+	assert.True(t, suite.inTearDownSubTest)
+	assert.True(t, suite.inTearDownTest)
+	assert.True(t, suite.inTearDownSuite)
+}